diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-08-28 15:08:00 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-08-28 15:08:07 -0700 |
| commit | e44acbf338e17fb86a47eebf448c27a04d446048 (patch) | |
| tree | dce45fa28ffd070c70ae2c0b27ad9794489cec6a /syntax_tree.moon | |
| parent | 930d522fbc3ab57faa926ed85f0d35d661722402 (diff) | |
Lots of overhaul, supporting a new Object Oriented approach (e.g.
%obj::action 1 2) and syntax.
Diffstat (limited to 'syntax_tree.moon')
| -rw-r--r-- | syntax_tree.moon | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/syntax_tree.moon b/syntax_tree.moon index 7132c64..bbb7c78 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -10,7 +10,7 @@ AST.is_syntax_tree = (n, t=nil)-> type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) and (t == nil or n.type == t) types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry", - "IndexChain", "Action", "FileChunks"} + "IndexChain", "Action", "FileChunks", "Method"} for name in *types cls = {} with cls @@ -19,49 +19,57 @@ for name in *types .__name = name .type = name .is_instance = (x)=> getmetatable(x) == @ - .__tostring = => - args = {tostring(@source), unpack(@)} - "#{@type}(#{concat([repr(v) for v in *args], ', ')})" + .__tostring = => "#{@type}#{repr @, ((x)-> Source\is_instance(x) and tostring(x) or nil)}" + .__repr = => "#{@type}#{repr @, ((x)-> Source\is_instance(x) and tostring(x) or nil)}" .map = (fn)=> replacement = fn(@) if replacement == false then return nil if replacement - -- Clone the replacement, but give it a proper source - replacement = (replacement.__class)(@source, unpack(replacement)) + -- Clone the replacement, so we can give it a proper source/comments + if AST.is_syntax_tree(replacement) + replacement = setmetatable {k,v for k,v in pairs replacement}, getmetatable(replacement) + replacement.source = @source + replacement.comments = {unpack(@comments)} if @comments else - replacements = {} + replacement = {source:@source, comments:@comments and {unpack(@comments)}} changes = false - for i,v in ipairs(@) - replacements[#replacements+1] = v + for k,v in pairs(@) + replacement[k] = v if AST.is_syntax_tree(v) r = v\map(fn) continue if r == v or r == nil changes = true - replacements[#replacements] = r + replacement[k] = r return @ unless changes - replacement = (@__class)(@source, unpack(replacements)) - replacement.comments = [c for c in *@comments] if @comments + replacement = setmetatable replacement, getmetatable(@) return replacement .__eq = (other)=> return false if type(@) != type(other) or #@ != #other or getmetatable(@) != getmetatable(other) for i=1,#@ return false if @[i] != other[i] + return false if @target != other.target return true AST[name] = setmetatable cls, __tostring: => @__name - __call: (source, ...)=> - if type(source) == 'string' - source = Source\from_string(source) - for i=1,select('#', ...) do assert(select(i,...)) - assert(Source\is_instance(source)) - inst = {:source, ...} - setmetatable(inst, @) - if inst.__init then inst\__init! - return inst + __call: (t)=> + if type(t.source) == 'string' + t.source = Source\from_string(t.source) + else + assert(Source\is_instance(t.source)) + setmetatable(t, @) + if t.__init then t\__init! + return t AST.Action.__init = => - stub_bits = [type(a) == 'string' and a or '%' for a in *@] + stub_bits = {} + arg_i = 1 + for a in *@ + if type(a) == 'string' + stub_bits[#stub_bits+1] = a + else + stub_bits[#stub_bits+1] = tostring(arg_i) + arg_i += 1 @stub = concat stub_bits, " " AST.Action.get_args = => |
