From 79d4bd5125de7ff220fbf8a8a5493d437ed16963 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 18 Sep 2018 19:48:58 -0700 Subject: Got rid of repr() use and replaced with :as_lua() or :as_nomsu() in as many places as possible. --- syntax_tree.moon | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'syntax_tree.moon') diff --git a/syntax_tree.moon b/syntax_tree.moon index 305a1ee..d2f5d37 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -1,6 +1,5 @@ -- This file contains the datastructures used to represent parsed Nomsu syntax trees, -- as well as the logic for converting them to Lua code. -{:repr} = require 'utils' {:insert, :remove, :concat} = table {:Source} = require "code_obj" unpack or= table.unpack @@ -9,6 +8,14 @@ AST = {} 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) +as_lua = => + if type(@) == 'number' + return tostring(@) + if mt = getmetatable(@) + if _as_lua = mt.as_lua + return _as_lua(@) + error("Not supported: #{@}") + types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry", "IndexChain", "Action", "FileChunks", "Error", "Comment"} for name in *types @@ -19,8 +26,18 @@ for name in *types .__name = name .type = name .is_instance = (x)=> getmetatable(x) == @ - .__tostring = => "#{@type}#{repr @, (->)}" - .__repr = => "#{@type}#{repr @, (->)}" + .__tostring = => + bits = [tostring(b) for b in *@] + for k,v in pairs(@) + unless bits[k] + table.insert(bits, "[ #{tostring(k)}]=#{tostring(v)}") + return "#{@type}{#{table.concat(bits, ", ")}}" + .as_lua = => + bits = [as_lua(b) for b in *@] + for k,v in pairs(@) + unless bits[k] + table.insert(bits, "[ #{as_lua(k)}]=#{as_lua(v)}") + return "#{@type}{#{table.concat(bits, ", ")}}" .source_code_for_tree = setmetatable({}, {__index:(t)=> s = t.source Files = require 'files' -- cgit v1.2.3 From 63d8b1cd3f34b15bf86210b99209e8b57e7019bb Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 28 Sep 2018 22:15:06 -0700 Subject: Fully working, I think? (with a lot of shims) --- syntax_tree.moon | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'syntax_tree.moon') diff --git a/syntax_tree.moon b/syntax_tree.moon index d2f5d37..926ea09 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -6,7 +6,7 @@ unpack or= table.unpack AST = {} 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) + type(n) == 'table' and getmetatable(n) and getmetatable(n).__type == "Syntax Tree" and (t == nil or n.type == t) as_lua = => if type(@) == 'number' @@ -25,6 +25,7 @@ for name in *types .__index = cls .__name = name .type = name + .__type = "Syntax Tree" .is_instance = (x)=> getmetatable(x) == @ .__tostring = => bits = [tostring(b) for b in *@] -- cgit v1.2.3 From 2f68357cb6800e97edd31abfc707d7c7905faa64 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 3 Oct 2018 16:26:24 -0700 Subject: Some incremental progress. --- syntax_tree.moon | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'syntax_tree.moon') diff --git a/syntax_tree.moon b/syntax_tree.moon index 926ea09..f3d3aee 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -82,8 +82,8 @@ for name in *types __call: (t)=> if type(t.source) == 'string' t.source = Source\from_string(t.source) - else - assert(Source\is_instance(t.source)) + --else + -- assert(Source\is_instance(t.source)) setmetatable(t, @) if init = t.__init then init(t) return t -- cgit v1.2.3 From d0c3c57f7b25c8d912c426e48cb5ab09cd738f65 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 31 Oct 2018 15:54:18 -0700 Subject: Simplified AST to just use a single moonscript class called "SyntaxTree" instead of a different metatable for each type of syntax tree. --- syntax_tree.moon | 164 +++++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 85 deletions(-) (limited to 'syntax_tree.moon') diff --git a/syntax_tree.moon b/syntax_tree.moon index f3d3aee..228f560 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -4,10 +4,6 @@ {:Source} = require "code_obj" unpack or= table.unpack -AST = {} -AST.is_syntax_tree = (n, t=nil)-> - type(n) == 'table' and getmetatable(n) and getmetatable(n).__type == "Syntax Tree" and (t == nil or n.type == t) - as_lua = => if type(@) == 'number' return tostring(@) @@ -16,90 +12,88 @@ as_lua = => return _as_lua(@) error("Not supported: #{@}") -types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry", - "IndexChain", "Action", "FileChunks", "Error", "Comment"} -for name in *types - cls = {} - with cls - .__class = cls - .__index = cls - .__name = name - .type = name - .__type = "Syntax Tree" - .is_instance = (x)=> getmetatable(x) == @ - .__tostring = => - bits = [tostring(b) for b in *@] - for k,v in pairs(@) - unless bits[k] - table.insert(bits, "[ #{tostring(k)}]=#{tostring(v)}") - return "#{@type}{#{table.concat(bits, ", ")}}" - .as_lua = => - bits = [as_lua(b) for b in *@] +--types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry", +-- "IndexChain", "Action", "FileChunks", "Error", "Comment"} +class SyntaxTree + @__type: "Syntax Tree" + + __tostring: => + bits = [tostring(b) for b in *@] + for k,v in pairs(@) + unless bits[k] + table.insert(bits, "[ #{tostring(k)}]=#{tostring(v)}") + return "SyntaxTree{#{table.concat(bits, ", ")}}" + + __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 + + as_lua: => + bits = [as_lua(b) for b in *@] + for k,v in pairs(@) + unless bits[k] + table.insert(bits, "[ #{as_lua(k)}]=#{as_lua(v)}") + return "SyntaxTree{#{table.concat(bits, ", ")}}" + + @source_code_for_tree: setmetatable({}, {__index:(t)=> + s = t.source + Files = require 'files' + f = Files.read(s.filename) + return f + }) + get_source_code: => @@source_code_for_tree[@] + map: (fn)=> + replacement = fn(@) + if replacement == false then return nil + if replacement + -- Clone the replacement, so we can give it a proper source/comments + if SyntaxTree\is_instance(replacement) + replacement = {k,v for k,v in pairs replacement} + replacement.source = @source + replacement.comments = {unpack(@comments)} if @comments + replacement = SyntaxTree(replacement) + else + replacement = {source:@source, comments:@comments and {unpack(@comments)}} + changes = false for k,v in pairs(@) - unless bits[k] - table.insert(bits, "[ #{as_lua(k)}]=#{as_lua(v)}") - return "#{@type}{#{table.concat(bits, ", ")}}" - .source_code_for_tree = setmetatable({}, {__index:(t)=> - s = t.source - Files = require 'files' - f = Files.read(s.filename) - return f - }) - .get_source_code = => @source_code_for_tree[@] - .map = (fn)=> - replacement = fn(@) - if replacement == false then return nil - if 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 - if init = replacement.__init then init(replacement) + replacement[k] = v + if SyntaxTree\is_instance(v) + r = v\map(fn) + continue if r == v or r == nil + changes = true + replacement[k] = r + return @ unless changes + replacement = SyntaxTree(replacement) + return replacement + + get_args: => + assert(@type == "Action", "Only actions have arguments") + return [tok for tok in *@ when type(tok) != 'string'] + + get_stub: => + stub_bits = {} + arg_i = 1 + for a in *@ + if type(a) == 'string' + stub_bits[#stub_bits+1] = a else - replacement = {source:@source, comments:@comments and {unpack(@comments)}} - changes = false - 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 - replacement[k] = r - return @ unless changes - replacement = setmetatable replacement, getmetatable(@) - if init = replacement.__init then init(replacement) - 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 + stub_bits[#stub_bits+1] = tostring(arg_i) + arg_i += 1 + return concat stub_bits, " " - AST[name] = setmetatable cls, - __tostring: => @__name - __call: (t)=> - if type(t.source) == 'string' - t.source = Source\from_string(t.source) - --else - -- assert(Source\is_instance(t.source)) - setmetatable(t, @) - if init = t.__init then init(t) - return t + @is_instance: (t)=> + type(t) == 'table' and getmetatable(t) == @__base -AST.Action.__init = => - 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 = => - [tok for tok in *@ when type(tok) != 'string'] +getmetatable(SyntaxTree).__call = (t)=> + if type(t.source) == 'string' + t.source = Source\from_string(t.source) + setmetatable(t, @__base) + if t.type == 'Action' + t.stub = t\get_stub! + return t -return AST +return SyntaxTree -- cgit v1.2.3 From 307dea18815ba4a06a3098edb170d7ad90708815 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 2 Nov 2018 14:38:24 -0700 Subject: Changed stub convention to (foo 1 baz 2) -> foo_1_baz instead of foo_1_baz_2, removed "smext", made some cleanup changes. --- syntax_tree.moon | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'syntax_tree.moon') diff --git a/syntax_tree.moon b/syntax_tree.moon index 228f560..03596f8 100644 --- a/syntax_tree.moon +++ b/syntax_tree.moon @@ -80,8 +80,10 @@ class SyntaxTree if type(a) == 'string' stub_bits[#stub_bits+1] = a else - stub_bits[#stub_bits+1] = tostring(arg_i) + stub_bits[#stub_bits+1] = arg_i arg_i += 1 + while type(stub_bits[#stub_bits]) == 'number' + stub_bits[#stub_bits] = nil return concat stub_bits, " " @is_instance: (t)=> -- cgit v1.2.3