des.lua 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. local unique_name = require"bon".unique_name
  2. local function pass_destandardify(chu)
  3. local function is_builtin_method(c)
  4. if c.type ~= 'dot' then
  5. return false
  6. end
  7. if c.a.et and c.a.et.type == 'list' and c.b == 'pop' then
  8. return {change_stmt = function(stmt)
  9. assert(stmt.type == 'call')
  10. local temp = {et = stmt.what.a.et, name = unique_name()}
  11. return {
  12. {
  13. type = 'let',
  14. var = temp,
  15. expr = stmt.what.a
  16. },
  17. {
  18. type = 'assign',
  19. dest = {
  20. type = 'index',
  21. what = {type = 'var', which = temp, et = temp.et},
  22. idx = {type = 'lengthof', sub = {type = 'var', which = temp, et = temp.et}, et = {type = 'integer'}}
  23. },
  24. src = {type = 'null', et = {type = 'null'}}
  25. },
  26. }
  27. end}
  28. end
  29. return false
  30. end
  31. if chu.type == "chunk" then
  32. for k, t in pairs(chu.types) do
  33. for _, m in pairs(t.members) do
  34. if m.type == "field" then
  35. -- Do nothing.
  36. elseif m.type == "static" then
  37. pass_destandardify(m.value)
  38. else
  39. error("Invalid AST")
  40. end
  41. end
  42. end
  43. local stmtIdx = 1
  44. while stmtIdx <= #chu.stmts do
  45. local stmt = chu.stmts[stmtIdx]
  46. local builtinmethod = stmt.type == 'call' and is_builtin_method(stmt.what)
  47. if builtinmethod then
  48. table.remove(chu.stmts, stmtIdx)
  49. for p, o in ipairs(builtinmethod.change_stmt(stmt)) do
  50. table.insert(chu.stmts, stmtIdx + p - 1, o)
  51. end
  52. else
  53. pass_destandardify(stmt)
  54. stmtIdx = stmtIdx + 1
  55. end
  56. end
  57. elseif chu.type == 'function' then
  58. pass_destandardify(chu.chunk)
  59. elseif chu.type == 'if' then
  60. for i = 1, #chu do
  61. pass_destandardify(chu[i].chu)
  62. end
  63. if chu.elsa then
  64. pass_destandardify(chu.elsa)
  65. end
  66. elseif chu.type == 'fori' then
  67. pass_destandardify(chu.chu)
  68. elseif chu.type == 'loop' then
  69. pass_destandardify(chu.chu)
  70. end
  71. end
  72. return pass_destandardify