From 72d699fe86ddb34473b54a0df27d21b4a9159284 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 5 Feb 2019 15:45:27 -0800 Subject: Bunch of changes: - Added shebangs to generated code output - SyntaxTree:map() -> SyntaxTree:with(), and corresponding changes to metaprogramming API - Added (return Lua 1) shorthand for (return (Lua 1)) - (1 and 2 and 3) compile rule mapping to -> (1 and (*extra arguments*)) - Don't scan for errors, just report them when compiling - Syntax changes: - Added prefix actions (e.g. #$foo) - Operator chars now include utf8 chars - Ditch "escaped nomsu" type (use (\ 1) compile action instead) --- nomsu_compiler.lua | 58 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 8 deletions(-) (limited to 'nomsu_compiler.lua') diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua index c9a15db..2521ce1 100644 --- a/nomsu_compiler.lua +++ b/nomsu_compiler.lua @@ -21,7 +21,7 @@ fail_at = function(source, msg) source = source.source elseif type(source) == 'string' then source = Source:from_string(source) - else + elseif not Source:is_instance(source) then assert(source.short_src and source.currentline) file = Files.read(source.short_src) assert(file, "Could not find " .. tostring(source.short_src)) @@ -86,6 +86,26 @@ compile = function(self, tree) end return lua end + if not compile_action then + local seen_words = { } + local words = { } + for word in stub:gmatch("[^0-9 ][^ ]*") do + if not (seen_words[word]) then + seen_words[word] = true + table.insert(words, word) + end + end + table.sort(words) + local stub2 = table.concat(words, " ") + compile_action = self.COMPILE_RULES[stub2] + if compile_action then + if debug.getinfo(compile_action, 'u').isvararg then + stub = stub2 + else + compile_action = nil + end + end + end if compile_action then local args do @@ -118,7 +138,7 @@ compile = function(self, tree) lua:add((stub):as_lua_id(), "(") for argnum, arg in ipairs(tree:get_args()) do local arg_lua = self:compile(arg) - if arg.type == "Block" then + if arg.type == "Block" and #arg > 1 then arg_lua = LuaCode:from(arg.source, "(function()\n ", arg_lua, "\nend)()") end if lua:trailing_line_len() + #arg_lua:text() > MAX_LINE then @@ -155,15 +175,22 @@ compile = function(self, tree) if not (target_text:match("^%(.*%)$") or target_text:match("^[_a-zA-Z][_a-zA-Z0-9.]*$") or tree[1].type == "IndexChain") then target_lua:parenthesize() end + local self_lua = #tree > 2 and "_self" or target_lua + if #tree > 2 then + lua:add("(function(", self_lua, ")\n ") + end for i = 2, #tree do if i > 2 then - lua:add("\n") + lua:add("\n ") end - lua:add(target_lua, ":") + if i > 2 and i == #tree then + lua:add("return ") + end + lua:add(self_lua, ":") lua:add((tree[i].stub):as_lua_id(), "(") for argnum, arg in ipairs(tree[i]:get_args()) do local arg_lua = self:compile(arg) - if arg.type == "Block" then + if arg.type == "Block" and #arg > 1 then arg_lua = LuaCode:from(arg.source, "(function()\n ", arg_lua, "\nend)()") end if lua:trailing_line_len() + #arg_lua:text() > MAX_LINE then @@ -175,6 +202,9 @@ compile = function(self, tree) end lua:add(")") end + if #tree > 2 then + lua:add("\nend)(", target_lua, ")") + end return lua elseif "EscapedNomsu" == _exp_0 then local lua = LuaCode:from(tree.source, "SyntaxTree{") @@ -320,9 +350,9 @@ compile = function(self, tree) items_lua:add("\n") sep = '' elseif items_lua:trailing_line_len() > MAX_LINE then - sep = ',\n ' + sep = items_lua:text():sub(-1) == ";" and "\n " or ",\n " else - sep = ', ' + sep = items_lua:text():sub(-1) == ";" and " " or ", " end i = i + 1 end @@ -360,6 +390,9 @@ compile = function(self, tree) if lua:text():match("['\"}]$") or lua:text():match("]=*]$") then lua:parenthesize() end + if lua:text() == "..." then + return LuaCode:from(tree.source, "select(", self:compile(tree[2][1]), ", ...)") + end for i = 2, #tree do local key = tree[i] if key.type ~= "Index" then @@ -381,7 +414,16 @@ compile = function(self, tree) elseif "Comment" == _exp_0 then return LuaCode:from(tree.source, "-- ", (tree[1]:gsub('\n', '\n-- '))) elseif "Error" == _exp_0 then - return error("Can't compile errors") + local err_msg = pretty_error({ + title = "Parse error", + error = tree.error, + hint = tree.hint, + source = tree:get_source_file(), + start = tree.source.start, + stop = tree.source.stop, + filename = tree.source.filename + }) + return error(err_msg) else return error("Unknown type: " .. tostring(tree.type)) end -- cgit v1.2.3