diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-05-16 15:44:07 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-05-16 15:45:59 -0700 |
| commit | af9dc0702568dc45b8809523dde760bb99aafbcb (patch) | |
| tree | 8334bab3a859aaa12ae5cb9f78b92f2eea5477b4 /nomsu_tree.lua | |
| parent | 3ffeaf1f5dbf3e225dc536066d0fedda3f38ac70 (diff) | |
Converted DictEntry to be an actual tree, instead of a pseudo-tree, made 'parse % as %'
generate lua code with already-substituted tree literals instead of reparsing and
substituting at parse time, and made some general optimizations.
Diffstat (limited to 'nomsu_tree.lua')
| -rw-r--r-- | nomsu_tree.lua | 239 |
1 files changed, 89 insertions, 150 deletions
diff --git a/nomsu_tree.lua b/nomsu_tree.lua index 1132dac..68475f6 100644 --- a/nomsu_tree.lua +++ b/nomsu_tree.lua @@ -14,12 +14,6 @@ do end local MAX_LINE = 80 local Types = { } -Types.DictEntry = immutable({ - "key", - "value" -}, { - name = "DictEntry" -}) Types.is_node = function(n) return type(n) == 'userdata' and getmetatable(n) and Types[n.type] == getmetatable(n) end @@ -46,6 +40,28 @@ Tree = function(name, methods) local ret = tostring(self.source:get_text()):gsub("\n" .. ((" "):rep(leading_space)), "\n") return ret end + methods.map = function(self, fn) + do + local mapped = fn(self) + if mapped then + return mapped + end + end + if Tuple:is_instance(self.value) then + return self:with_value(Tuple(unpack((function() + local _accum_0 = { } + local _len_0 = 1 + local _list_0 = self.value + for _index_0 = 1, #_list_0 do + local v = _list_0[_index_0] + _accum_0[_len_0] = v.map and v:map(fn) or v + _len_0 = _len_0 + 1 + end + return _accum_0 + end)()))) + end + return self + end end Types[name] = immutable({ "value", @@ -66,9 +82,6 @@ Tree("Nomsu", { return nomsu and Nomsu(self.source, "\\:\n ", nomsu) end return nomsu and Nomsu(self.source, "\\(", nomsu, ")") - end, - map = function(self, fn) - return fn(self) or self:with_value(self.value:map(fn)) end }) Tree("Block", { @@ -113,19 +126,6 @@ Tree("Block", { end end return nomsu - end, - map = function(self, fn) - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local v = _list_0[_index_0] - _accum_0[_len_0] = v:map(fn) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)()))) end }) local math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]]) @@ -349,19 +349,6 @@ Tree("Action", { end return nomsu end - end, - map = function(self, fn) - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local v = _list_0[_index_0] - _accum_0[_len_0] = v:map(fn) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)()))) end }) Tree("Text", { @@ -469,19 +456,6 @@ Tree("Text", { end return nomsu end - end, - map = function(self, fn) - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local v = _list_0[_index_0] - _accum_0[_len_0] = type(v) == 'string' and v or v:map(fn) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)()))) end }) Tree("List", { @@ -568,19 +542,6 @@ Tree("List", { end return nomsu end - end, - map = function(self, fn) - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local v = _list_0[_index_0] - _accum_0[_len_0] = v:map(fn) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)()))) end }) Tree("Dict", { @@ -588,29 +549,14 @@ Tree("Dict", { local lua = Lua.Value(self.source, "{") local line_length = 0 for i, entry in ipairs(self.value) do - local key_lua = entry.key:as_lua(nomsu) - if not (key_lua.is_value) then - local line, src = key.source:get_line(), key.source:get_text() - error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict key, since it's not an expression.", 0) - end - local value_lua = entry.value and entry.value:as_lua(nomsu) or Lua.Value(entry.key.source, "true") - if not (value_lua.is_value) then - local line, src = value.source:get_line(), value.source:get_text() - error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict value, since it's not an expression.", 0) - end - local key_str = tostring(key_lua):match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=]) - if key_str then - lua:append(key_str, "=", value_lua) - elseif tostring(key_lua):sub(1, 1) == "[" then - lua:append("[ ", key_lua, "]=", value_lua) - else - lua:append("[", key_lua, "]=", value_lua) - end - local newlines, last_line = ("[" .. tostring(key_lua) .. "=" .. tostring(value_lua)):match("^(.-)([^\n]*)$") - if #newlines > 0 then + local entry_lua = entry:as_lua(nomsu) + lua:append(entry_lua) + local entry_lua_str = tostring(entry_lua) + local last_line = entry_lua_str:match("\n([^\n]*)$") + if last_line then line_length = #last_line else - line_length = line_length + #last_line + line_length = line_length + #entry_lua_str end if i < #self.value then if line_length >= MAX_LINE then @@ -632,21 +578,14 @@ Tree("Dict", { if inline then local nomsu = Nomsu(self.source, "{") for i, entry in ipairs(self.value) do - local key_nomsu = entry.key:as_nomsu(true) - if not (key_nomsu) then - return nil - end - if entry.key.type == "Action" or entry.key.type == "Block" then - key_nomsu:parenthesize() - end - local value_nomsu = entry.value and entry.value:as_nomsu(true) or Nomsu(entry.key.source, "") - if not (value_nomsu) then + local entry_nomsu = entry:as_nomsu(true) + if not (entry_nomsu) then return nil end if i > 1 then nomsu:append(", ") end - nomsu:append(key_nomsu, ":", value_nomsu) + nomsu:append(entry_nomsu) end nomsu:append("}") return nomsu @@ -660,37 +599,21 @@ Tree("Dict", { local _list_0 = self.value for _index_0 = 1, #_list_0 do local entry = _list_0[_index_0] - local key_nomsu = entry.key:as_nomsu(true) - if not (key_nomsu) then + local entry_nomsu = entry:as_nomsu() + if not (entry_nomsu) then return nil end - if entry.key.type == "Action" or entry.key.type == "Block" then - key_nomsu:parenthesize() - end - local value_nomsu = entry.value and entry.value:as_nomsu(true) or Nomsu(entry.key.source, "") - if value_nomsu and #line + #", " + #key_nomsu + #":" + #value_nomsu <= MAX_LINE then + if #line + #tostring(entry_nomsu) <= MAX_LINE then if #line.bits > 1 then line:append(", ") end - line:append(key_nomsu) - if entry.value then - line:append(":", value_nomsu) - end + line:append(entry_nomsu) else - if not (value_nomsu) then - value_nomsu = entry.value:as_nomsu() - if not (value_nomsu) then - return nil - end - end if #line.bits > 1 then nomsu:append(line) line = Nomsu(bit.source, "\n ") end - line:append(key_nomsu) - if entry.value then - line:append(":", value_nomsu) - end + line:append(entry_nomsu) end end if #line.bits > 1 then @@ -698,20 +621,61 @@ Tree("Dict", { end return nomsu end + end +}) +Tree("DictEntry", { + as_lua = function(self, nomsu) + local key, value = self.value[1], self.value[2] + local key_lua = key:as_lua(nomsu) + if not (key_lua.is_value) then + local line, src = key.source:get_line(), key.source:get_text() + error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict key, since it's not an expression.", 0) + end + local value_lua = value and value:as_lua(nomsu) or Lua.Value(key.source, "true") + if not (value_lua.is_value) then + local line, src = value.source:get_line(), value.source:get_text() + error(tostring(line) .. ": Cannot use " .. tostring(colored.yellow(src)) .. " as a dict value, since it's not an expression.", 0) + end + local key_str = tostring(key_lua):match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=]) + if key_str then + return Lua(key.source, key_str, "=", value_lua) + elseif tostring(key_lua):sub(1, 1) == "[" then + return Lua(key.source, "[ ", key_lua, "]=", value_lua) + else + return Lua(key.source, "[", key_lua, "]=", value_lua) + end end, - map = function(self, fn) - local DictEntry = Types.DictEntry - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local e = _list_0[_index_0] - _accum_0[_len_0] = DictEntry(e.key:map(fn), e.value:map(fn)) - _len_0 = _len_0 + 1 + as_nomsu = function(self, inline) + if inline == nil then + inline = true + end + local key, value = self.value[1], self.value[2] + local key_nomsu = key:as_nomsu(true) + if not (key_nomsu) then + return nil + end + if key.type == "Action" or key.type == "Block" then + key_nomsu:parenthesize() + end + local value_nomsu + if value then + value_nomsu = value:as_nomsu(true) + else + value_nomsu = Nomsu(key.source, "") + end + if inline and not value_nomsu then + return nil + end + if not value_nomsu then + if inline then + return nil + end + value_nomsu = value:as_nomsu() + if not (value_nomsu) then + return nil end - return _accum_0 - end)()))) + end + return Nomsu(key.source, key_nomsu, ":", value_nomsu) end }) Tree("IndexChain", { @@ -771,19 +735,6 @@ Tree("IndexChain", { nomsu:append(bit_nomsu) end return nomsu - end, - map = function(self, fn) - return fn(self) or self:with_value(Tuple(unpack((function() - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = self.value - for _index_0 = 1, #_list_0 do - local v = _list_0[_index_0] - _accum_0[_len_0] = v:map(fn) - _len_0 = _len_0 + 1 - end - return _accum_0 - end)()))) end }) Tree("Number", { @@ -795,9 +746,6 @@ Tree("Number", { inline = false end return Nomsu(self.source, tostring(self.value)) - end, - map = function(self, fn) - return fn(self) or self end }) Tree("Var", { @@ -818,9 +766,6 @@ Tree("Var", { inline = false end return Nomsu(self.source, "%", self.value) - end, - map = function(self, fn) - return fn(self) or self end }) Tree("Word", { @@ -832,9 +777,6 @@ Tree("Word", { inline = false end return Nomsu(self.source, self.value) - end, - map = function(self, fn) - return fn(self) or self end }) Tree("Comment", { @@ -853,9 +795,6 @@ Tree("Comment", { else return Nomsu(self.source, "#", self.value) end - end, - map = function(self, fn) - return fn(self) or self end }) return Types |
