aboutsummaryrefslogtreecommitdiff
path: root/syntax_tree.lua
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-10-31 15:54:18 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-10-31 15:54:51 -0700
commitd0c3c57f7b25c8d912c426e48cb5ab09cd738f65 (patch)
treebc783d59d13c859343a9225f003062adb455ecac /syntax_tree.lua
parentec92b0fccd70f06b5348fa355f49557aa71fdb3c (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.lua220
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