diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2018-10-31 15:54:18 -0700 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2018-10-31 15:54:51 -0700 |
| commit | d0c3c57f7b25c8d912c426e48cb5ab09cd738f65 (patch) | |
| tree | bc783d59d13c859343a9225f003062adb455ecac /syntax_tree.lua | |
| parent | ec92b0fccd70f06b5348fa355f49557aa71fdb3c (diff) | |
Simplified AST to just use a single moonscript class called "SyntaxTree"
instead of a different metatable for each type of syntax tree.
Diffstat (limited to 'syntax_tree.lua')
| -rw-r--r-- | syntax_tree.lua | 220 |
1 files changed, 96 insertions, 124 deletions
diff --git a/syntax_tree.lua b/syntax_tree.lua index 63c24ee..92cee59 100644 --- a/syntax_tree.lua +++ b/syntax_tree.lua @@ -6,13 +6,6 @@ end local Source Source = require("code_obj").Source local unpack = unpack or table.unpack -local AST = { } -AST.is_syntax_tree = function(n, t) - if t == nil then - t = nil - end - return type(n) == 'table' and getmetatable(n) and getmetatable(n).__type == "Syntax Tree" and (t == nil or n.type == t) -end local as_lua as_lua = function(self) if type(self) == 'number' then @@ -31,40 +24,17 @@ as_lua = function(self) end return error("Not supported: " .. tostring(self)) end -local types = { - "Number", - "Var", - "Block", - "EscapedNomsu", - "Text", - "List", - "Dict", - "DictEntry", - "IndexChain", - "Action", - "FileChunks", - "Error", - "Comment" -} -for _index_0 = 1, #types do - local name = types[_index_0] - local cls = { } - do - cls.__class = cls - cls.__index = cls - cls.__name = name - cls.type = name - cls.__type = "Syntax Tree" - cls.is_instance = function(self, x) - return getmetatable(x) == self - end - cls.__tostring = function(self) +local SyntaxTree +do + local _class_0 + local _base_0 = { + __tostring = function(self) local bits do local _accum_0 = { } local _len_0 = 1 - for _index_1 = 1, #self do - local b = self[_index_1] + for _index_0 = 1, #self do + local b = self[_index_0] _accum_0[_len_0] = tostring(b) _len_0 = _len_0 + 1 end @@ -75,15 +45,29 @@ for _index_0 = 1, #types do table.insert(bits, "[ " .. tostring(tostring(k)) .. "]=" .. tostring(tostring(v))) end end - return tostring(self.type) .. "{" .. tostring(table.concat(bits, ", ")) .. "}" - end - cls.as_lua = function(self) + return "SyntaxTree{" .. tostring(table.concat(bits, ", ")) .. "}" + end, + __eq = function(self, other) + if type(self) ~= type(other) or #self ~= #other or getmetatable(self) ~= getmetatable(other) then + return false + end + for i = 1, #self do + if self[i] ~= other[i] then + return false + end + end + if self.target ~= other.target then + return false + end + return true + end, + as_lua = function(self) local bits do local _accum_0 = { } local _len_0 = 1 - for _index_1 = 1, #self do - local b = self[_index_1] + for _index_0 = 1, #self do + local b = self[_index_0] _accum_0[_len_0] = as_lua(b) _len_0 = _len_0 + 1 end @@ -94,45 +78,32 @@ for _index_0 = 1, #types do table.insert(bits, "[ " .. tostring(as_lua(k)) .. "]=" .. tostring(as_lua(v))) end end - return tostring(self.type) .. "{" .. tostring(table.concat(bits, ", ")) .. "}" - end - cls.source_code_for_tree = setmetatable({ }, { - __index = function(self, t) - local s = t.source - local Files = require('files') - local f = Files.read(s.filename) - return f - end - }) - cls.get_source_code = function(self) - return self.source_code_for_tree[self] - end - cls.map = function(self, fn) + return "SyntaxTree{" .. tostring(table.concat(bits, ", ")) .. "}" + end, + get_source_code = function(self) + return self.__class.source_code_for_tree[self] + end, + map = function(self, fn) local replacement = fn(self) if replacement == false then return nil end if replacement then - if AST.is_syntax_tree(replacement) then - replacement = setmetatable((function() + if SyntaxTree:is_instance(replacement) then + do local _tbl_0 = { } for k, v in pairs(replacement) do _tbl_0[k] = v end - return _tbl_0 - end)(), getmetatable(replacement)) + replacement = _tbl_0 + end replacement.source = self.source if self.comments then replacement.comments = { unpack(self.comments) } end - do - local init = replacement.__init - if init then - init(replacement) - end - end + replacement = SyntaxTree(replacement) end else replacement = { @@ -146,7 +117,7 @@ for _index_0 = 1, #types do local _continue_0 = false repeat replacement[k] = v - if AST.is_syntax_tree(v) then + if SyntaxTree:is_instance(v) then local r = v:map(fn) if r == v or r == nil then _continue_0 = true @@ -164,74 +135,75 @@ for _index_0 = 1, #types do if not (changes) then return self end - replacement = setmetatable(replacement, getmetatable(self)) - do - local init = replacement.__init - if init then - init(replacement) - end - end + replacement = SyntaxTree(replacement) end return replacement - end - cls.__eq = function(self, other) - if type(self) ~= type(other) or #self ~= #other or getmetatable(self) ~= getmetatable(other) then - return false - end - for i = 1, #self do - if self[i] ~= other[i] then - return false + end, + get_args = function(self) + assert(self.type == "Action", "Only actions have arguments") + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #self do + local tok = self[_index_0] + if type(tok) ~= 'string' then + _accum_0[_len_0] = tok + _len_0 = _len_0 + 1 end end - if self.target ~= other.target then - return false - end - return true - end - end - AST[name] = setmetatable(cls, { - __tostring = function(self) - return self.__name + return _accum_0 end, - __call = function(self, t) - if type(t.source) == 'string' then - t.source = Source:from_string(t.source) - end - setmetatable(t, self) - do - local init = t.__init - if init then - init(t) + get_stub = function(self) + local stub_bits = { } + local arg_i = 1 + for _index_0 = 1, #self do + local a = self[_index_0] + if type(a) == 'string' then + stub_bits[#stub_bits + 1] = a + else + stub_bits[#stub_bits + 1] = tostring(arg_i) + arg_i = arg_i + 1 end end - return t + return concat(stub_bits, " ") + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function() end, + __base = _base_0, + __name = "SyntaxTree" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 end }) -end -AST.Action.__init = function(self) - local stub_bits = { } - local arg_i = 1 - for _index_0 = 1, #self do - local a = self[_index_0] - if type(a) == 'string' then - stub_bits[#stub_bits + 1] = a - else - stub_bits[#stub_bits + 1] = tostring(arg_i) - arg_i = arg_i + 1 + _base_0.__class = _class_0 + local self = _class_0 + self.__type = "Syntax Tree" + self.source_code_for_tree = setmetatable({ }, { + __index = function(self, t) + local s = t.source + local Files = require('files') + local f = Files.read(s.filename) + return f end + }) + self.is_instance = function(self, t) + return type(t) == 'table' and getmetatable(t) == self.__base end - self.stub = concat(stub_bits, " ") + SyntaxTree = _class_0 end -AST.Action.get_args = function(self) - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #self do - local tok = self[_index_0] - if type(tok) ~= 'string' then - _accum_0[_len_0] = tok - _len_0 = _len_0 + 1 - end +getmetatable(SyntaxTree).__call = function(self, t) + if type(t.source) == 'string' then + t.source = Source:from_string(t.source) + end + setmetatable(t, self.__base) + if t.type == 'Action' then + t.stub = t:get_stub() end - return _accum_0 + return t end -return AST +return SyntaxTree |
