diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-06-12 18:04:18 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-06-12 18:04:41 -0700 |
| commit | 3c510e4ee5027aa5191e994bdf0a080a32a4b082 (patch) | |
| tree | b8d740f6ce0e263faa92967a63d16af07f3d45e7 /nomsu_tree.lua | |
| parent | b5fb8933af283d2b873a03ded085e8b69f374e81 (diff) | |
Lots of optimizations and simplifications, especially towards getting
better performance on luajit.
Diffstat (limited to 'nomsu_tree.lua')
| -rw-r--r-- | nomsu_tree.lua | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/nomsu_tree.lua b/nomsu_tree.lua index 5aeefe8..96e5031 100644 --- a/nomsu_tree.lua +++ b/nomsu_tree.lua @@ -12,17 +12,18 @@ AST.is_syntax_tree = function(n) return type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) end local Tree -Tree = function(name, leaf_or_branch, methods) +Tree = function(name, methods) local cls = methods or { } - local is_multi = leaf_or_branch == 'branch' do cls.type = name + cls.__class = cls + cls.__name = name cls.is_instance = function(self, x) return getmetatable(x) == self end cls.__index = cls cls.__tostring = function(self) - return tostring(self.name) .. "(#{@value and repr(@value) or table.concat([repr(v) for v in *@]), ', '})" + return tostring(self.name) .. "(#{table.concat([repr(v) for v in *@]), ', '})" end cls.map = function(self, fn) do @@ -31,21 +32,26 @@ Tree = function(name, leaf_or_branch, methods) return replacement end end - if self.value then - return self - end - local new_vals - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #self do - local v = self[_index_0] - _accum_0[_len_0] = v.map and v:map(fn) or v - _len_0 = _len_0 + 1 + local made_changes, new_vals = false, { } + for i, v in ipairs(self) do + if AST.is_syntax_tree(v) then + do + local replacement = v:map(fn) + if replacement then + if replacement ~= v then + made_changes = true + v = replacement + end + end + end end - new_vals = _accum_0 + new_vals[i] = v end - return getmetatable(self)(self.source, unpack(new_vals)) + if not (made_changes) then + return self + end + local replacement = getmetatable(self)(self.source, unpack(new_vals)) + return replacement end end AST[name] = setmetatable(cls, { @@ -57,18 +63,10 @@ Tree = function(name, leaf_or_branch, methods) source = Source:from_string(source) end assert(Source:is_instance(source)) - local inst - if is_multi then - inst = { - source = source, - ... - } - else - inst = { - source = source, - value = ... - } - end + local inst = { + source = source, + ... + } setmetatable(inst, self) if inst.__init then inst:__init() @@ -77,16 +75,16 @@ Tree = function(name, leaf_or_branch, methods) end }) end -Tree("Number", 'leaf') -Tree("Var", 'leaf') -Tree("Block", 'branch') -Tree("EscapedNomsu", 'branch') -Tree("Text", 'branch') -Tree("List", 'branch') -Tree("Dict", 'branch') -Tree("DictEntry", 'branch') -Tree("IndexChain", 'branch') -Tree("Action", 'branch', { +Tree("Number") +Tree("Var") +Tree("Block") +Tree("EscapedNomsu") +Tree("Text") +Tree("List") +Tree("Dict") +Tree("DictEntry") +Tree("IndexChain") +Tree("Action", { __init = function(self) local stub_bits do @@ -107,7 +105,7 @@ Tree("Action", 'branch', { local _len_0 = 1 for _index_0 = 1, #self do local a = self[_index_0] - _accum_0[_len_0] = type(a) == "string" and a or "%" .. tostring(a.value) + _accum_0[_len_0] = type(a) == "string" and a or "%" .. tostring(a[1]) _len_0 = _len_0 + 1 end return _accum_0 |
