From 19405a4d8e1abada16524f0f0d948a5392a2210b Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 24 Nov 2025 18:56:35 +0100 Subject: [PATCH 01/11] feat: add prefix attributes in variables declarations --- candran/can-parser/parser.lua | 5 +++-- compiler/lua53.can | 3 +++ compiler/lua54.can | 10 +++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/candran/can-parser/parser.lua b/candran/can-parser/parser.lua index 5b44859..9964c08 100644 --- a/candran/can-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -585,8 +585,9 @@ local G = { V"Lua", ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList")) / markImplicit; NameList = tagC("NameList", commaSep(V"Id")); - DestructuringNameList = tagC("NameList", commaSep(V"DestructuringId")), - AttributeNameList = tagC("AttributeNameList", commaSep(V"AttributeId")); + DestructuringNameList = tagC("NameList", commaSep(V"DestructuringId")); + AttributeNameList = tagC("AttributeNameList", commaSep(V"AttributeId")) + + tagC("PrefixedAttributeNameList", V"Attribute" * commaSep(V"AttributeId")); VarList = tagC("VarList", commaSep(V"VarExpr")); ExprList = tagC("ExpList", commaSep(V"Expr", "ExprList")); diff --git a/compiler/lua53.can b/compiler/lua53.can index ab354f7..e71ab55 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -8,6 +8,9 @@ tags.AttributeId = (t) return t[1] end end +tags.PrefixedAttributeNameList = (t) + error("target "..targetName.." does not support variable attributes") +end #placeholder("patch") diff --git a/compiler/lua54.can b/compiler/lua54.can index 49bf3a1..fcfc2ef 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -465,7 +465,7 @@ return function(code, ast, options, macros={functions={}, variables={}}) -- Local{ {attributeident+} {expr+}? } Local = (t) local destructured = {} - local r = "local "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") + local r = "local "..push("destructuring", destructured)..lua(t[1])..pop("destructuring") if t[2][1] then r ..= " = "..lua(t[2], "_lhs") end @@ -822,6 +822,14 @@ return function(code, ast, options, macros={functions={}, variables={}}) end return r end, + -- PrefixedAttributeNameList{ attribute {AttributeId+} } + PrefixedAttributeNameList = (t) + return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) + end, + -- AttributeNameList{ {AttributeId+} } + AttributeNameList = (t) + return lua(t, "_lhs") + end, -- AttributeId{ ? } AttributeId = (t) if t[2] then From e2a1c51c2d7eab6b8003f06abbbbe24aa164baed Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 24 Nov 2025 18:58:30 +0100 Subject: [PATCH 02/11] feat: start work on Lua 5.5 --- candran.can | 5 +- compiler/lua54.can | 909 +-------------------------------------------- compiler/lua55.can | 906 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 916 insertions(+), 904 deletions(-) create mode 100644 compiler/lua55.can diff --git a/candran.can b/candran.can index 78a7be4..29e73e2 100644 --- a/candran.can +++ b/candran.can @@ -6,6 +6,7 @@ package.loaded["candran"] = candran #import("candran.util") #import("candran.serpent") +#import("compiler.lua55") #import("compiler.lua54") #import("compiler.lua53") #import("compiler.lua52") @@ -21,7 +22,7 @@ local unpack = unpack or table.unpack --- Default options. candran.default = { - target = "lua54", + target = "lua55", indentation = "", newline = "\n", variablePrefix = "__CAN_", @@ -44,6 +45,8 @@ elseif _VERSION == "Lua 5.2" then candran.default.target = "lua52" elseif _VERSION == "Lua 5.3" then candran.default.target = "lua53" +elseif _VERSION == "Lua 5.4" then + candran.default.target = "lua54" end --- Run the preprocessor diff --git a/compiler/lua54.can b/compiler/lua54.can index fcfc2ef..e9c6d98 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -1,906 +1,9 @@ -local util = require("candran.util") +targetName = "Lua 5.4" -local targetName = "Lua 5.4" +#placeholder("patch") -local unpack = unpack or table.unpack +#local patch = output +#output = "" +#import("compiler.lua55", { preprocessorEnv = { patch = patch }, loadPackage = false }) -return function(code, ast, options, macros={functions={}, variables={}}) - --- Line mapping - local lastInputPos = 1 -- last token position in the input code - local prevLinePos = 1 -- last token position in the previous line of code in the input code - local lastSource = options.chunkname or "nil" -- last found code source name (from the original file) - local lastLine = 1 -- last found line number (from the original file) - - --- Newline management - local indentLevel = 0 - -- Returns a newline. - local function newline() - local r = options.newline..string.rep(options.indentation, indentLevel) - if options.mapLines then - local sub = code:sub(lastInputPos) - local source, line = sub:sub(1, sub:find("\n")):match(".*%-%- (.-)%:(%d+)\n") - - if source and line then - lastSource = source - lastLine = tonumber(line) - else - for _ in code:sub(prevLinePos, lastInputPos):gmatch("\n") do - lastLine += 1 - end - end - - prevLinePos = lastInputPos - - r = " -- "..lastSource..":"..lastLine..r - end - return r - end - -- Returns a newline and add one level of indentation. - local function indent() - indentLevel += 1 - return newline() - end - -- Returns a newline and remove one level of indentation. - local function unindent() - indentLevel -= 1 - return newline() - end - - --- State stacks - -- Used for context-sensitive syntax. - local states = { - push = {}, -- push stack variable names - destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} - scope = {}, -- list of variables defined in the current scope - macroargs = {} -- currently defined arguemnts from a macro function - } - -- Push a new value on top of the stack "name". Returns an empty string for chaining. - local function push(name, state) - table.insert(states[name], state) - return "" - end - -- Remove the value on top of the stack "name". Returns an empty string for chaining. - local function pop(name) - table.remove(states[name]) - return "" - end - -- Set the value on top of the stack "name". Returns an empty string for chaining. - local function set(name, state) - states[name][#states[name]] = state - return "" - end - -- Returns the value on top of the stack "name". - local function peek(name) - return states[name][#states[name]] - end - - --- Variable management - -- Returns the prefixed variable name. - local function var(name) - return options.variablePrefix..name - end - - -- Returns the prefixed temporary variable name. - local function tmp() - local scope = peek("scope") - local var = "%s_%s":format(options.variablePrefix, #scope) - table.insert(scope, var) - return var - end - - -- indicate if currently processing a macro, so it cannot be applied recursively - local nomacro = { variables = {}, functions = {} } - - --- Module management - local required = {} -- { ["full require expression"] = true, ... } - local requireStr = "" - -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". - local function addRequire(mod, name, field) - local req = "require(%q)%s":format(mod, field and "."..field or "") - if not required[req] then - requireStr ..= "local %s = %s%s":format(var(name), req, options.newline) - required[req] = true - end - end - - --- AST traversal helpers - local loop = { "While", "Repeat", "Fornum", "Forin", "WhileExpr", "RepeatExpr", "FornumExpr", "ForinExpr" } -- loops tags (can contain continue) - local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags (can contain push) - - -- Returns the first node or subnode from the list "list" which tag is in the list "tags", or nil if there were none. - -- Won't recursively follow nodes which have a tag in "nofollow". - local function any(list, tags, nofollow={}) - local tagsCheck = {} - for _, tag in ipairs(tags) do - tagsCheck[tag] = true - end - local nofollowCheck = {} - for _, tag in ipairs(nofollow) do - nofollowCheck[tag] = true - end - for _, node in ipairs(list) do - if type(node) == "table" then - if tagsCheck[node.tag] then - return node - end - if not nofollowCheck[node.tag] then - local r = any(node, tags, nofollow) - if r then return r end - end - end - end - return nil - end - - -- Like any, but returns a list of every node found. - -- Order: in the order of the list, from the deepest to the nearest - local function search(list, tags, nofollow={}) - local tagsCheck = {} - for _, tag in ipairs(tags) do - tagsCheck[tag] = true - end - local nofollowCheck = {} - for _, tag in ipairs(nofollow) do - nofollowCheck[tag] = true - end - local found = {} - for _, node in ipairs(list) do - if type(node) == "table" then - if not nofollowCheck[node.tag] then - for _, n in ipairs(search(node, tags, nofollow)) do - table.insert(found, n) - end - end - if tagsCheck[node.tag] then - table.insert(found, node) - end - end - end - return found - end - - -- Returns true if the all the nodes in list have their type in tags. - local function all(list, tags) - for _, node in ipairs(list) do - local ok = false - for _, tag in ipairs(tags) do - if node.tag == tag then - ok = true - break - end - end - if not ok then - return false - end - end - return true - end - - --- Lua compiler - local tags - -- Recursively returns the compiled AST Lua code, set "forceTag" to override the tag type and pass additional arguments to the tag constructor if needed. - local function lua(ast, forceTag, ...) - if options.mapLines and ast.pos then - lastInputPos = ast.pos - end - return tags[forceTag or ast.tag](ast, ...) - end - - --- Lua function calls writer - local UNPACK = (list, i, j) -- table.unpack - return "table.unpack("..list..(i and (", "..i..(j and (", "..j) or "")) or "")..")" - end - local APPEND = (t, toAppend) -- append values "toAppend" (multiple values possible) to t - return "do"..indent().."local "..var("a").." = table.pack("..toAppend..")"..newline().."table.move("..var("a")..", 1, "..var("a")..".n, #"..t.."+1, "..t..")"..unindent().."end" - end - local CONTINUE_START = () -- at the start of loops using continue - return "do"..indent() - end - local CONTINUE_STOP = () -- at the start of loops using continue - return unindent().."end"..newline().."::"..var"continue".."::" - end - local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement - local vars = {} - local values = {} - for _, list in ipairs(destructured) do - for _, v in ipairs(list) do - local var, val - if v.tag == "Id" or v.tag == "AttributeId" then - var = v - val = { tag = "Index", { tag = "Id", list.id }, { tag = "String", v[1] } } - elseif v.tag == "Pair" then - var = v[2] - val = { tag = "Index", { tag = "Id", list.id }, v[1] } - else - error("unknown destructuring element type: "..tostring(v.tag)) - end - if destructured.rightOp and destructured.leftOp then - val = { tag = "Op", destructured.rightOp, var, { tag = "Op", destructured.leftOp, val, var } } - elseif destructured.rightOp then - val = { tag = "Op", destructured.rightOp, var, val } - elseif destructured.leftOp then - val = { tag = "Op", destructured.leftOp, val, var } - end - table.insert(vars, lua(var)) - table.insert(values, lua(val)) - end - end - if #vars > 0 then - local decl = noLocal and "" or "local " - if newlineAfter then - return decl..table.concat(vars, ", ").." = "..table.concat(values, ", ")..newline() - else - return newline()..decl..table.concat(vars, ", ").." = "..table.concat(values, ", ") - end - else - return "" - end - end - - --- Tag constructors - tags = setmetatable({ - -- block: { stat* } -- - Block = (t) - local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined - if hasPush and hasPush == t[#t] then -- if the first push is the last statement, it's just a return - hasPush.tag = "Return" - hasPush = false - end - local r = push("scope", {}) - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - end - for i=1, #t-1, 1 do - r ..= lua(t[i])..newline() - end - if t[#t] then - r ..= lua(t[#t]) - end - if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed - r ..= newline().."return "..UNPACK(var"push")..pop("push") - end - return r..pop("scope") - end, - - -- stat -- - - -- Do{ stat* } - Do = (t) - return "do"..indent()..lua(t, "Block")..unindent().."end" - end, - -- Set{ {lhs+} (opid? = opid?)? {expr+} } - Set = (t) - -- extract vars and values - local expr = t[#t] - local vars, values = {}, {} - local destructuringVars, destructuringValues = {}, {} - for i, n in ipairs(t[1]) do - if n.tag == "DestructuringId" then - table.insert(destructuringVars, n) - table.insert(destructuringValues, expr[i]) - else - table.insert(vars, n) - table.insert(values, expr[i]) - end - end - -- - if #t == 2 or #t == 3 then - local r = "" - if #vars > 0 then - r = lua(vars, "_lhs").." = "..lua(values, "_lhs") - end - if #destructuringVars > 0 then - local destructured = {} - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - elseif #t == 4 then - if t[3] == "=" then - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Paren", values[1] } }, "Op") - for i=2, math.min(#t[4], #vars), 1 do - r ..= ", "..lua({ t[2], vars[i], { tag = "Paren", values[i] } }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { rightOp = t[2] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - else - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[3], { tag = "Paren", values[1] }, vars[1] }, "Op") - for i=2, math.min(#t[4], #t[1]), 1 do - r ..= ", "..lua({ t[3], { tag = "Paren", values[i] }, vars[i] }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { leftOp = t[3] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - end - else -- You are mad. - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Op", t[4], { tag = "Paren", values[1] }, vars[1] } }, "Op") - for i=2, math.min(#t[5], #t[1]), 1 do - r ..= ", "..lua({ t[2], vars[i], { tag = "Op", t[4], { tag = "Paren", values[i] }, vars[i] } }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { rightOp = t[2], leftOp = t[4] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - end - end, - -- While{ expr block } - While = (t) - local r = "" - local hasContinue = any(t[2], { "Continue" }, loop) - local lets = search({ t[1] }, { "LetExpr" }) - if #lets > 0 then - r ..= "do"..indent() - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - end - r ..= "while "..lua(t[1]).." do"..indent() - if #lets > 0 then - r ..= "do"..indent() - end - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[2]) - if hasContinue then - r ..= CONTINUE_STOP() - end - r ..= unindent().."end" - if #lets > 0 then - for _, l in ipairs(lets) do - r ..= newline()..lua(l, "Set") - end - r ..= unindent().."end"..unindent().."end" - end - return r - end, - -- Repeat{ block expr } - Repeat = (t) - local hasContinue = any(t[1], { "Continue" }, loop) - local r = "repeat"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[1]) - if hasContinue then - r ..= CONTINUE_STOP() - end - r ..= unindent().."until "..lua(t[2]) - return r - end, - -- If{ (lexpr block)+ block? } - If = (t) - local r = "" - local toClose = 0 -- blocks that need to be closed at the end of the if - local lets = search({ t[1] }, { "LetExpr" }) - if #lets > 0 then - r ..= "do"..indent() - toClose += 1 - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - end - r ..= "if "..lua(t[1]).." then"..indent()..lua(t[2])..unindent() - for i=3, #t-1, 2 do - lets = search({ t[i] }, { "LetExpr" }) - if #lets > 0 then - r ..= "else"..indent() - toClose += 1 - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - else - r ..= "else" - end - r ..= "if "..lua(t[i]).." then"..indent()..lua(t[i+1])..unindent() - end - if #t % 2 == 1 then - r ..= "else"..indent()..lua(t[#t])..unindent() - end - r ..= "end" - for i=1, toClose do - r ..= unindent().."end" - end - return r - end, - -- Fornum{ ident expr expr expr? block } - Fornum = (t) - local r = "for "..lua(t[1]).." = "..lua(t[2])..", "..lua(t[3]) - if #t == 5 then - local hasContinue = any(t[5], { "Continue" }, loop) - r ..= ", "..lua(t[4]).." do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[5]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - else - local hasContinue = any(t[4], { "Continue" }, loop) - r ..= " do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[4]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - end - end, - -- Forin{ {ident+} {expr+} block } - Forin = (t) - local destructured = {} - local hasContinue = any(t[3], { "Continue" }, loop) - local r = "for "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring").." in "..lua(t[2], "_lhs").." do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= DESTRUCTURING_ASSIGN(destructured, true)..lua(t[3]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - end, - -- Local{ {attributeident+} {expr+}? } - Local = (t) - local destructured = {} - local r = "local "..push("destructuring", destructured)..lua(t[1])..pop("destructuring") - if t[2][1] then - r ..= " = "..lua(t[2], "_lhs") - end - return r..DESTRUCTURING_ASSIGN(destructured) - end, - -- Let{ {ident+} {expr+}? } - Let = (t) - local destructured = {} - local nameList = push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") - local r = "local "..nameList - if t[2][1] then - if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here - r ..= " = "..lua(t[2], "_lhs") - else - r ..= newline()..nameList.." = "..lua(t[2], "_lhs") - end - end - return r..DESTRUCTURING_ASSIGN(destructured) - end, - -- Localrec{ {ident} {expr} } - Localrec = (t) - return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") - end, - -- Goto{ } - Goto = (t) - return "goto "..lua(t, "Id") - end, - -- Label{ } - Label = (t) - return "::"..lua(t, "Id").."::" - end, - -- Return{ } - Return = (t) - local push = peek("push") - if push then - local r = "" - for _, val in ipairs(t) do - r ..= push.."[#"..push.."+1] = "..lua(val)..newline() - end - return r.."return "..UNPACK(push) - else - return "return "..lua(t, "_lhs") - end - end, - -- Push{ } - Push = (t) - local var = assert(peek("push"), "no context given for push") - r = "" - for i=1, #t-1, 1 do - r ..= var.."[#"..var.."+1] = "..lua(t[i])..newline() - end - if t[#t] then - if t[#t].tag == "Call" then - r ..= APPEND(var, lua(t[#t])) - else - r ..= var.."[#"..var.."+1] = "..lua(t[#t]) - end - end - return r - end, - -- Break - Break = () - return "break" - end, - -- Continue - Continue = () - return "goto "..var"continue" - end, - -- apply (below) - - -- expr -- - - -- Nil - Nil = () - return "nil" - end, - -- Dots - Dots = () - local macroargs = peek("macroargs") - if macroargs and not nomacro.variables["..."] and macroargs["..."] then - nomacro.variables["..."] = true - local r = lua(macroargs["..."], "_lhs") - nomacro.variables["..."] = nil - return r - else - return "..." - end - end, - -- Boolean{ } - Boolean = (t) - return tostring(t[1]) - end, - -- Number{ } - Number = (t) - return tostring(t[1]) - end, - -- String{ } - String = (t) - return "%q":format(t[1]) - end, - -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } - _functionWithoutKeyword = (t) - local r = "(" - local decl = {} - if t[1][1] then - if t[1][1].tag == "ParPair" then - local id = lua(t[1][1][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") - indentLevel -= 1 - r ..= id - else - r ..= lua(t[1][1]) - end - for i=2, #t[1], 1 do - if t[1][i].tag == "ParPair" then - local id = lua(t[1][i][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") - indentLevel -= 1 - r ..= ", " ..id - else - r ..= ", "..lua(t[1][i]) - end - end - end - r ..= ")"..indent() - for _, d in ipairs(decl) do - r ..= d..newline() - end - if t[2][#t[2]] and t[2][#t[2]].tag == "Push" then -- convert final push to return - t[2][#t[2]].tag = "Return" - end - local hasPush = any(t[2], { "Push" }, func) - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - else - push("push", false) -- no push here (make sure higher push doesn't affect us) - end - r ..= lua(t[2]) - if hasPush and (t[2][#t[2]] and t[2][#t[2]].tag ~= "Return") then -- add return only if needed - r ..= newline().."return "..UNPACK(var"push") - end - pop("push") - return r..unindent().."end" - end, - Function = (t) - return "function"..lua(t, "_functionWithoutKeyword") - end, - -- Table{ ( `Pair{ expr expr } | expr )* } - Pair = (t) - return "["..lua(t[1]).."] = "..lua(t[2]) - end, - Table = (t) - if #t == 0 then - return "{}" - elseif #t == 1 then - return "{ "..lua(t, "_lhs").." }" - else - return "{"..indent()..lua(t, "_lhs", nil, true)..unindent().."}" - end - end, - -- TableCompr{ block } - TableCompr = (t) - return push("push", "self").."(function()"..indent().."local self = {}"..newline()..lua(t[1])..newline().."return self"..unindent().."end)()"..pop("push") - end, - -- Op{ opid expr expr? } - Op = (t) - local r - if #t == 2 then - if type(tags._opid[t[1]]) == "string" then - r = tags._opid[t[1]].." "..lua(t[2]) - else - r = tags._opid[t[1]](t[2]) - end - else - if type(tags._opid[t[1]]) == "string" then - r = lua(t[2]).." "..tags._opid[t[1]].." "..lua(t[3]) - else - r = tags._opid[t[1]](t[2], t[3]) - end - end - return r - end, - -- Paren{ expr } - Paren = (t) - return "("..lua(t[1])..")" - end, - -- MethodStub{ expr expr } - MethodStub = (t) - return "(function()"..indent() .. - "local "..var"object".." = "..lua(t[1])..newline().. - "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. - "if "..var"method".." == nil then return nil end"..newline().. - "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. - "end)()" - end, - -- SafeMethodStub{ expr expr } - SafeMethodStub = (t) - return "(function()"..indent() .. - "local "..var"object".." = "..lua(t[1])..newline().. - "if "..var"object".." == nil then return nil end"..newline().. - "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. - "if "..var"method".." == nil then return nil end"..newline().. - "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. - "end)()" - end, - -- statexpr (below) - -- apply (below) - -- lhs (below) - - -- lexpr -- - LetExpr = (t) - return lua(t[1][1]) - end, - - -- statexpr -- - _statexpr = (t, stat) - local hasPush = any(t, { "Push" }, func) - local r = "(function()"..indent() - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - else - push("push", false) -- no push here (make sure higher push don't affect us) - end - r ..= lua(t, stat) - if hasPush then - r ..= newline().."return "..UNPACK(var"push") - end - pop("push") - r ..= unindent().."end)()" - return r - end, - -- DoExpr{ stat* } - DoExpr = (t) - if t[#t].tag == "Push" then -- convert final push to return - t[#t].tag = "Return" - end - return lua(t, "_statexpr", "Do") - end, - -- WhileExpr{ expr block } - WhileExpr = (t) - return lua(t, "_statexpr", "While") - end, - -- RepeatExpr{ block expr } - RepeatExpr = (t) - return lua(t, "_statexpr", "Repeat") - end, - -- IfExpr{ (expr block)+ block? } - IfExpr = (t) - for i=2, #t do -- convert final pushes to returns - local block = t[i] - if block[#block] and block[#block].tag == "Push" then - block[#block].tag = "Return" - end - end - return lua(t, "_statexpr", "If") - end, - -- FornumExpr{ ident expr expr expr? block } - FornumExpr = (t) - return lua(t, "_statexpr", "Fornum") - end, - -- ForinExpr{ {ident+} {expr+} block } - ForinExpr = (t) - return lua(t, "_statexpr", "Forin") - end, - - -- apply -- - - -- Call{ expr expr* } - Call = (t) - if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" - elseif t[1].tag == "Id" and not nomacro.functions[t[1][1]] and macros.functions[t[1][1]] then - local macro = macros.functions[t[1][1]] - local replacement = macro.replacement - local r - nomacro.functions[t[1][1]] = true - if type(replacement) == "function" then - local args = {} - for i=2, #t do - table.insert(args, lua(t[i])) - end - r = replacement(unpack(args)) - else - local macroargs = util.merge(peek("macroargs")) - for i, arg in ipairs(macro.args) do - if arg.tag == "Dots" then - macroargs["..."] = [for j=i+1, #t do t[j] end] - elseif arg.tag == "Id" then - if t[i+1] == nil then - error("bad argument #%s to macro %s (value expected)":format(i, t[1][1])) - end - macroargs[arg[1]] = t[i+1] - else - error("unexpected argument type %s in macro %s":format(arg.tag, t[1][1])) - end - end - push("macroargs", macroargs) - r = lua(replacement) - pop("macroargs") - end - nomacro.functions[t[1][1]] = nil - return r - elseif t[1].tag == "MethodStub" then -- method call - if t[1][1].tag == "String" or t[1][1].tag == "Table" then - return "("..lua(t[1][1]).."):"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" - else - return lua(t[1][1])..":"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" - end - else - return lua(t[1]).."("..lua(t, "_lhs", 2)..")" - end - end, - -- SafeCall{ expr expr* } - SafeCall = (t) - if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) - return lua(t, "SafeIndex") - else -- no side effects possible - return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."("..lua(t, "_lhs", 2)..") or nil)" - end - end, - - -- lhs -- - _lhs = (t, start=1, newlines) - local r - if t[start] then - r = lua(t[start]) - for i=start+1, #t, 1 do - r ..= ","..(newlines and newline() or " ")..lua(t[i]) - end - else - r = "" - end - return r - end, - -- Id{ } - Id = (t) - local r = t[1] - local macroargs = peek("macroargs") - if not nomacro.variables[t[1]] then - nomacro.variables[t[1]] = true - if macroargs and macroargs[t[1]] then -- replace with macro argument - r = lua(macroargs[t[1]]) - elseif macros.variables[t[1]] ~= nil then -- replace with macro variable - local macro = macros.variables[t[1]] - if type(macro) == "function" then - r = macro() - else - r = lua(macro) - end - end - nomacro.variables[t[1]] = nil - end - return r - end, - -- PrefixedAttributeNameList{ attribute {AttributeId+} } - PrefixedAttributeNameList = (t) - return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) - end, - -- AttributeNameList{ {AttributeId+} } - AttributeNameList = (t) - return lua(t, "_lhs") - end, - -- AttributeId{ ? } - AttributeId = (t) - if t[2] then - return t[1] .. " <" .. t[2] .. ">" - else - return t[1] - end - end, - -- DestructuringId{ Id | Pair+ } - DestructuringId = (t) - if t.id then -- destructing already done before, use parent variable as id - return t.id - else - local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") - local vars = { id = tmp() } - for j=1, #t, 1 do - table.insert(vars, t[j]) - end - table.insert(d, vars) - t.id = vars.id - return vars.id - end - end, - -- Index{ expr expr } - Index = (t) - if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1])..")["..lua(t[2]).."]" - else - return lua(t[1]).."["..lua(t[2]).."]" - end - end, - -- SafeIndex{ expr expr } - SafeIndex = (t) - if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) - local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) - while t.tag == "SafeIndex" or t.tag == "SafeCall" do - table.insert(l, 1, t) - t = t[1] - end - local r = "(function()"..indent().."local "..var"safe".." = "..lua(l[1][1])..newline() -- base expr - for _, e in ipairs(l) do - r ..= "if "..var"safe".." == nil then return nil end"..newline() - if e.tag == "SafeIndex" then - r ..= var"safe".." = "..var"safe".."["..lua(e[2]).."]"..newline() - else - r ..= var"safe".." = "..var"safe".."("..lua(e, "_lhs", 2)..")"..newline() - end - end - r ..= "return "..var"safe"..unindent().."end)()" - return r - else -- no side effects possible - return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."["..lua(t[2]).."] or nil)" - end - end, - - -- opid -- - _opid = { - add = "+", sub = "-", mul = "*", div = "/", - idiv = "//", mod = "%", pow = "^", concat = "..", - band = "&", bor = "|", bxor = "~", shl = "<<", shr = ">>", - eq = "==", ne = "~=", lt = "<", gt = ">", le = "<=", ge = ">=", - ["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not" - } - }, { - __index = (self, key) - error("don't know how to compile a "..tostring(key).." to "..targetName) - end - }) - - #placeholder("patch") - - local code = lua(ast)..newline() - return requireStr..code -end +return lua55 diff --git a/compiler/lua55.can b/compiler/lua55.can new file mode 100644 index 0000000..a55d1c7 --- /dev/null +++ b/compiler/lua55.can @@ -0,0 +1,906 @@ +local util = require("candran.util") + +local targetName = "Lua 5.5" + +local unpack = unpack or table.unpack + +return function(code, ast, options, macros={functions={}, variables={}}) + --- Line mapping + local lastInputPos = 1 -- last token position in the input code + local prevLinePos = 1 -- last token position in the previous line of code in the input code + local lastSource = options.chunkname or "nil" -- last found code source name (from the original file) + local lastLine = 1 -- last found line number (from the original file) + + --- Newline management + local indentLevel = 0 + -- Returns a newline. + local function newline() + local r = options.newline..string.rep(options.indentation, indentLevel) + if options.mapLines then + local sub = code:sub(lastInputPos) + local source, line = sub:sub(1, sub:find("\n")):match(".*%-%- (.-)%:(%d+)\n") + + if source and line then + lastSource = source + lastLine = tonumber(line) + else + for _ in code:sub(prevLinePos, lastInputPos):gmatch("\n") do + lastLine += 1 + end + end + + prevLinePos = lastInputPos + + r = " -- "..lastSource..":"..lastLine..r + end + return r + end + -- Returns a newline and add one level of indentation. + local function indent() + indentLevel += 1 + return newline() + end + -- Returns a newline and remove one level of indentation. + local function unindent() + indentLevel -= 1 + return newline() + end + + --- State stacks + -- Used for context-sensitive syntax. + local states = { + push = {}, -- push stack variable names + destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} + scope = {}, -- list of variables defined in the current scope + macroargs = {} -- currently defined arguemnts from a macro function + } + -- Push a new value on top of the stack "name". Returns an empty string for chaining. + local function push(name, state) + table.insert(states[name], state) + return "" + end + -- Remove the value on top of the stack "name". Returns an empty string for chaining. + local function pop(name) + table.remove(states[name]) + return "" + end + -- Set the value on top of the stack "name". Returns an empty string for chaining. + local function set(name, state) + states[name][#states[name]] = state + return "" + end + -- Returns the value on top of the stack "name". + local function peek(name) + return states[name][#states[name]] + end + + --- Variable management + -- Returns the prefixed variable name. + local function var(name) + return options.variablePrefix..name + end + + -- Returns the prefixed temporary variable name. + local function tmp() + local scope = peek("scope") + local var = "%s_%s":format(options.variablePrefix, #scope) + table.insert(scope, var) + return var + end + + -- indicate if currently processing a macro, so it cannot be applied recursively + local nomacro = { variables = {}, functions = {} } + + --- Module management + local required = {} -- { ["full require expression"] = true, ... } + local requireStr = "" + -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". + local function addRequire(mod, name, field) + local req = "require(%q)%s":format(mod, field and "."..field or "") + if not required[req] then + requireStr ..= "local %s = %s%s":format(var(name), req, options.newline) + required[req] = true + end + end + + --- AST traversal helpers + local loop = { "While", "Repeat", "Fornum", "Forin", "WhileExpr", "RepeatExpr", "FornumExpr", "ForinExpr" } -- loops tags (can contain continue) + local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags (can contain push) + + -- Returns the first node or subnode from the list "list" which tag is in the list "tags", or nil if there were none. + -- Won't recursively follow nodes which have a tag in "nofollow". + local function any(list, tags, nofollow={}) + local tagsCheck = {} + for _, tag in ipairs(tags) do + tagsCheck[tag] = true + end + local nofollowCheck = {} + for _, tag in ipairs(nofollow) do + nofollowCheck[tag] = true + end + for _, node in ipairs(list) do + if type(node) == "table" then + if tagsCheck[node.tag] then + return node + end + if not nofollowCheck[node.tag] then + local r = any(node, tags, nofollow) + if r then return r end + end + end + end + return nil + end + + -- Like any, but returns a list of every node found. + -- Order: in the order of the list, from the deepest to the nearest + local function search(list, tags, nofollow={}) + local tagsCheck = {} + for _, tag in ipairs(tags) do + tagsCheck[tag] = true + end + local nofollowCheck = {} + for _, tag in ipairs(nofollow) do + nofollowCheck[tag] = true + end + local found = {} + for _, node in ipairs(list) do + if type(node) == "table" then + if not nofollowCheck[node.tag] then + for _, n in ipairs(search(node, tags, nofollow)) do + table.insert(found, n) + end + end + if tagsCheck[node.tag] then + table.insert(found, node) + end + end + end + return found + end + + -- Returns true if the all the nodes in list have their type in tags. + local function all(list, tags) + for _, node in ipairs(list) do + local ok = false + for _, tag in ipairs(tags) do + if node.tag == tag then + ok = true + break + end + end + if not ok then + return false + end + end + return true + end + + --- Lua compiler + local tags + -- Recursively returns the compiled AST Lua code, set "forceTag" to override the tag type and pass additional arguments to the tag constructor if needed. + local function lua(ast, forceTag, ...) + if options.mapLines and ast.pos then + lastInputPos = ast.pos + end + return tags[forceTag or ast.tag](ast, ...) + end + + --- Lua function calls writer + local UNPACK = (list, i, j) -- table.unpack + return "table.unpack("..list..(i and (", "..i..(j and (", "..j) or "")) or "")..")" + end + local APPEND = (t, toAppend) -- append values "toAppend" (multiple values possible) to t + return "do"..indent().."local "..var("a").." = table.pack("..toAppend..")"..newline().."table.move("..var("a")..", 1, "..var("a")..".n, #"..t.."+1, "..t..")"..unindent().."end" + end + local CONTINUE_START = () -- at the start of loops using continue + return "do"..indent() + end + local CONTINUE_STOP = () -- at the start of loops using continue + return unindent().."end"..newline().."::"..var"continue".."::" + end + local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement + local vars = {} + local values = {} + for _, list in ipairs(destructured) do + for _, v in ipairs(list) do + local var, val + if v.tag == "Id" or v.tag == "AttributeId" then + var = v + val = { tag = "Index", { tag = "Id", list.id }, { tag = "String", v[1] } } + elseif v.tag == "Pair" then + var = v[2] + val = { tag = "Index", { tag = "Id", list.id }, v[1] } + else + error("unknown destructuring element type: "..tostring(v.tag)) + end + if destructured.rightOp and destructured.leftOp then + val = { tag = "Op", destructured.rightOp, var, { tag = "Op", destructured.leftOp, val, var } } + elseif destructured.rightOp then + val = { tag = "Op", destructured.rightOp, var, val } + elseif destructured.leftOp then + val = { tag = "Op", destructured.leftOp, val, var } + end + table.insert(vars, lua(var)) + table.insert(values, lua(val)) + end + end + if #vars > 0 then + local decl = noLocal and "" or "local " + if newlineAfter then + return decl..table.concat(vars, ", ").." = "..table.concat(values, ", ")..newline() + else + return newline()..decl..table.concat(vars, ", ").." = "..table.concat(values, ", ") + end + else + return "" + end + end + + --- Tag constructors + tags = setmetatable({ + -- block: { stat* } -- + Block = (t) + local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined + if hasPush and hasPush == t[#t] then -- if the first push is the last statement, it's just a return + hasPush.tag = "Return" + hasPush = false + end + local r = push("scope", {}) + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + end + for i=1, #t-1, 1 do + r ..= lua(t[i])..newline() + end + if t[#t] then + r ..= lua(t[#t]) + end + if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed + r ..= newline().."return "..UNPACK(var"push")..pop("push") + end + return r..pop("scope") + end, + + -- stat -- + + -- Do{ stat* } + Do = (t) + return "do"..indent()..lua(t, "Block")..unindent().."end" + end, + -- Set{ {lhs+} (opid? = opid?)? {expr+} } + Set = (t) + -- extract vars and values + local expr = t[#t] + local vars, values = {}, {} + local destructuringVars, destructuringValues = {}, {} + for i, n in ipairs(t[1]) do + if n.tag == "DestructuringId" then + table.insert(destructuringVars, n) + table.insert(destructuringValues, expr[i]) + else + table.insert(vars, n) + table.insert(values, expr[i]) + end + end + -- + if #t == 2 or #t == 3 then + local r = "" + if #vars > 0 then + r = lua(vars, "_lhs").." = "..lua(values, "_lhs") + end + if #destructuringVars > 0 then + local destructured = {} + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + elseif #t == 4 then + if t[3] == "=" then + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Paren", values[1] } }, "Op") + for i=2, math.min(#t[4], #vars), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Paren", values[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + else + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[3], { tag = "Paren", values[1] }, vars[1] }, "Op") + for i=2, math.min(#t[4], #t[1]), 1 do + r ..= ", "..lua({ t[3], { tag = "Paren", values[i] }, vars[i] }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { leftOp = t[3] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + end + else -- You are mad. + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Op", t[4], { tag = "Paren", values[1] }, vars[1] } }, "Op") + for i=2, math.min(#t[5], #t[1]), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Op", t[4], { tag = "Paren", values[i] }, vars[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2], leftOp = t[4] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + end + end, + -- While{ expr block } + While = (t) + local r = "" + local hasContinue = any(t[2], { "Continue" }, loop) + local lets = search({ t[1] }, { "LetExpr" }) + if #lets > 0 then + r ..= "do"..indent() + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + end + r ..= "while "..lua(t[1]).." do"..indent() + if #lets > 0 then + r ..= "do"..indent() + end + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[2]) + if hasContinue then + r ..= CONTINUE_STOP() + end + r ..= unindent().."end" + if #lets > 0 then + for _, l in ipairs(lets) do + r ..= newline()..lua(l, "Set") + end + r ..= unindent().."end"..unindent().."end" + end + return r + end, + -- Repeat{ block expr } + Repeat = (t) + local hasContinue = any(t[1], { "Continue" }, loop) + local r = "repeat"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[1]) + if hasContinue then + r ..= CONTINUE_STOP() + end + r ..= unindent().."until "..lua(t[2]) + return r + end, + -- If{ (lexpr block)+ block? } + If = (t) + local r = "" + local toClose = 0 -- blocks that need to be closed at the end of the if + local lets = search({ t[1] }, { "LetExpr" }) + if #lets > 0 then + r ..= "do"..indent() + toClose += 1 + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + end + r ..= "if "..lua(t[1]).." then"..indent()..lua(t[2])..unindent() + for i=3, #t-1, 2 do + lets = search({ t[i] }, { "LetExpr" }) + if #lets > 0 then + r ..= "else"..indent() + toClose += 1 + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + else + r ..= "else" + end + r ..= "if "..lua(t[i]).." then"..indent()..lua(t[i+1])..unindent() + end + if #t % 2 == 1 then + r ..= "else"..indent()..lua(t[#t])..unindent() + end + r ..= "end" + for i=1, toClose do + r ..= unindent().."end" + end + return r + end, + -- Fornum{ ident expr expr expr? block } + Fornum = (t) + local r = "for "..lua(t[1]).." = "..lua(t[2])..", "..lua(t[3]) + if #t == 5 then + local hasContinue = any(t[5], { "Continue" }, loop) + r ..= ", "..lua(t[4]).." do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[5]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + else + local hasContinue = any(t[4], { "Continue" }, loop) + r ..= " do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[4]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + end + end, + -- Forin{ {ident+} {expr+} block } + Forin = (t) + local destructured = {} + local hasContinue = any(t[3], { "Continue" }, loop) + local r = "for "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring").." in "..lua(t[2], "_lhs").." do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= DESTRUCTURING_ASSIGN(destructured, true)..lua(t[3]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + end, + -- Local{ {attributeident+} {expr+}? } + Local = (t) + local destructured = {} + local r = "local "..push("destructuring", destructured)..lua(t[1])..pop("destructuring") + if t[2][1] then + r ..= " = "..lua(t[2], "_lhs") + end + return r..DESTRUCTURING_ASSIGN(destructured) + end, + -- Let{ {ident+} {expr+}? } + Let = (t) + local destructured = {} + local nameList = push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") + local r = "local "..nameList + if t[2][1] then + if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here + r ..= " = "..lua(t[2], "_lhs") + else + r ..= newline()..nameList.." = "..lua(t[2], "_lhs") + end + end + return r..DESTRUCTURING_ASSIGN(destructured) + end, + -- Localrec{ {ident} {expr} } + Localrec = (t) + return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") + end, + -- Goto{ } + Goto = (t) + return "goto "..lua(t, "Id") + end, + -- Label{ } + Label = (t) + return "::"..lua(t, "Id").."::" + end, + -- Return{ } + Return = (t) + local push = peek("push") + if push then + local r = "" + for _, val in ipairs(t) do + r ..= push.."[#"..push.."+1] = "..lua(val)..newline() + end + return r.."return "..UNPACK(push) + else + return "return "..lua(t, "_lhs") + end + end, + -- Push{ } + Push = (t) + local var = assert(peek("push"), "no context given for push") + r = "" + for i=1, #t-1, 1 do + r ..= var.."[#"..var.."+1] = "..lua(t[i])..newline() + end + if t[#t] then + if t[#t].tag == "Call" then + r ..= APPEND(var, lua(t[#t])) + else + r ..= var.."[#"..var.."+1] = "..lua(t[#t]) + end + end + return r + end, + -- Break + Break = () + return "break" + end, + -- Continue + Continue = () + return "goto "..var"continue" + end, + -- apply (below) + + -- expr -- + + -- Nil + Nil = () + return "nil" + end, + -- Dots + Dots = () + local macroargs = peek("macroargs") + if macroargs and not nomacro.variables["..."] and macroargs["..."] then + nomacro.variables["..."] = true + local r = lua(macroargs["..."], "_lhs") + nomacro.variables["..."] = nil + return r + else + return "..." + end + end, + -- Boolean{ } + Boolean = (t) + return tostring(t[1]) + end, + -- Number{ } + Number = (t) + return tostring(t[1]) + end, + -- String{ } + String = (t) + return "%q":format(t[1]) + end, + -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } + _functionWithoutKeyword = (t) + local r = "(" + local decl = {} + if t[1][1] then + if t[1][1].tag == "ParPair" then + local id = lua(t[1][1][1]) + indentLevel += 1 + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") + indentLevel -= 1 + r ..= id + else + r ..= lua(t[1][1]) + end + for i=2, #t[1], 1 do + if t[1][i].tag == "ParPair" then + local id = lua(t[1][i][1]) + indentLevel += 1 + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") + indentLevel -= 1 + r ..= ", " ..id + else + r ..= ", "..lua(t[1][i]) + end + end + end + r ..= ")"..indent() + for _, d in ipairs(decl) do + r ..= d..newline() + end + if t[2][#t[2]] and t[2][#t[2]].tag == "Push" then -- convert final push to return + t[2][#t[2]].tag = "Return" + end + local hasPush = any(t[2], { "Push" }, func) + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + else + push("push", false) -- no push here (make sure higher push doesn't affect us) + end + r ..= lua(t[2]) + if hasPush and (t[2][#t[2]] and t[2][#t[2]].tag ~= "Return") then -- add return only if needed + r ..= newline().."return "..UNPACK(var"push") + end + pop("push") + return r..unindent().."end" + end, + Function = (t) + return "function"..lua(t, "_functionWithoutKeyword") + end, + -- Table{ ( `Pair{ expr expr } | expr )* } + Pair = (t) + return "["..lua(t[1]).."] = "..lua(t[2]) + end, + Table = (t) + if #t == 0 then + return "{}" + elseif #t == 1 then + return "{ "..lua(t, "_lhs").." }" + else + return "{"..indent()..lua(t, "_lhs", nil, true)..unindent().."}" + end + end, + -- TableCompr{ block } + TableCompr = (t) + return push("push", "self").."(function()"..indent().."local self = {}"..newline()..lua(t[1])..newline().."return self"..unindent().."end)()"..pop("push") + end, + -- Op{ opid expr expr? } + Op = (t) + local r + if #t == 2 then + if type(tags._opid[t[1]]) == "string" then + r = tags._opid[t[1]].." "..lua(t[2]) + else + r = tags._opid[t[1]](t[2]) + end + else + if type(tags._opid[t[1]]) == "string" then + r = lua(t[2]).." "..tags._opid[t[1]].." "..lua(t[3]) + else + r = tags._opid[t[1]](t[2], t[3]) + end + end + return r + end, + -- Paren{ expr } + Paren = (t) + return "("..lua(t[1])..")" + end, + -- MethodStub{ expr expr } + MethodStub = (t) + return "(function()"..indent() .. + "local "..var"object".." = "..lua(t[1])..newline().. + "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. + "if "..var"method".." == nil then return nil end"..newline().. + "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. + "end)()" + end, + -- SafeMethodStub{ expr expr } + SafeMethodStub = (t) + return "(function()"..indent() .. + "local "..var"object".." = "..lua(t[1])..newline().. + "if "..var"object".." == nil then return nil end"..newline().. + "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. + "if "..var"method".." == nil then return nil end"..newline().. + "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. + "end)()" + end, + -- statexpr (below) + -- apply (below) + -- lhs (below) + + -- lexpr -- + LetExpr = (t) + return lua(t[1][1]) + end, + + -- statexpr -- + _statexpr = (t, stat) + local hasPush = any(t, { "Push" }, func) + local r = "(function()"..indent() + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + else + push("push", false) -- no push here (make sure higher push don't affect us) + end + r ..= lua(t, stat) + if hasPush then + r ..= newline().."return "..UNPACK(var"push") + end + pop("push") + r ..= unindent().."end)()" + return r + end, + -- DoExpr{ stat* } + DoExpr = (t) + if t[#t].tag == "Push" then -- convert final push to return + t[#t].tag = "Return" + end + return lua(t, "_statexpr", "Do") + end, + -- WhileExpr{ expr block } + WhileExpr = (t) + return lua(t, "_statexpr", "While") + end, + -- RepeatExpr{ block expr } + RepeatExpr = (t) + return lua(t, "_statexpr", "Repeat") + end, + -- IfExpr{ (expr block)+ block? } + IfExpr = (t) + for i=2, #t do -- convert final pushes to returns + local block = t[i] + if block[#block] and block[#block].tag == "Push" then + block[#block].tag = "Return" + end + end + return lua(t, "_statexpr", "If") + end, + -- FornumExpr{ ident expr expr expr? block } + FornumExpr = (t) + return lua(t, "_statexpr", "Fornum") + end, + -- ForinExpr{ {ident+} {expr+} block } + ForinExpr = (t) + return lua(t, "_statexpr", "Forin") + end, + + -- apply -- + + -- Call{ expr expr* } + Call = (t) + if t[1].tag == "String" or t[1].tag == "Table" then + return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" + elseif t[1].tag == "Id" and not nomacro.functions[t[1][1]] and macros.functions[t[1][1]] then + local macro = macros.functions[t[1][1]] + local replacement = macro.replacement + local r + nomacro.functions[t[1][1]] = true + if type(replacement) == "function" then + local args = {} + for i=2, #t do + table.insert(args, lua(t[i])) + end + r = replacement(unpack(args)) + else + local macroargs = util.merge(peek("macroargs")) + for i, arg in ipairs(macro.args) do + if arg.tag == "Dots" then + macroargs["..."] = [for j=i+1, #t do t[j] end] + elseif arg.tag == "Id" then + if t[i+1] == nil then + error("bad argument #%s to macro %s (value expected)":format(i, t[1][1])) + end + macroargs[arg[1]] = t[i+1] + else + error("unexpected argument type %s in macro %s":format(arg.tag, t[1][1])) + end + end + push("macroargs", macroargs) + r = lua(replacement) + pop("macroargs") + end + nomacro.functions[t[1][1]] = nil + return r + elseif t[1].tag == "MethodStub" then -- method call + if t[1][1].tag == "String" or t[1][1].tag == "Table" then + return "("..lua(t[1][1]).."):"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" + else + return lua(t[1][1])..":"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" + end + else + return lua(t[1]).."("..lua(t, "_lhs", 2)..")" + end + end, + -- SafeCall{ expr expr* } + SafeCall = (t) + if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) + return lua(t, "SafeIndex") + else -- no side effects possible + return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."("..lua(t, "_lhs", 2)..") or nil)" + end + end, + + -- lhs -- + _lhs = (t, start=1, newlines) + local r + if t[start] then + r = lua(t[start]) + for i=start+1, #t, 1 do + r ..= ","..(newlines and newline() or " ")..lua(t[i]) + end + else + r = "" + end + return r + end, + -- Id{ } + Id = (t) + local r = t[1] + local macroargs = peek("macroargs") + if not nomacro.variables[t[1]] then + nomacro.variables[t[1]] = true + if macroargs and macroargs[t[1]] then -- replace with macro argument + r = lua(macroargs[t[1]]) + elseif macros.variables[t[1]] ~= nil then -- replace with macro variable + local macro = macros.variables[t[1]] + if type(macro) == "function" then + r = macro() + else + r = lua(macro) + end + end + nomacro.variables[t[1]] = nil + end + return r + end, + -- PrefixedAttributeNameList{ attribute {AttributeId+} } + PrefixedAttributeNameList = (t) + return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) + end, + -- AttributeNameList{ {AttributeId+} } + AttributeNameList = (t) + return lua(t, "_lhs") + end, + -- AttributeId{ ? } + AttributeId = (t) + if t[2] then + return t[1] .. " <" .. t[2] .. ">" + else + return t[1] + end + end, + -- DestructuringId{ Id | Pair+ } + DestructuringId = (t) + if t.id then -- destructing already done before, use parent variable as id + return t.id + else + local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") + local vars = { id = tmp() } + for j=1, #t, 1 do + table.insert(vars, t[j]) + end + table.insert(d, vars) + t.id = vars.id + return vars.id + end + end, + -- Index{ expr expr } + Index = (t) + if t[1].tag == "String" or t[1].tag == "Table" then + return "("..lua(t[1])..")["..lua(t[2]).."]" + else + return lua(t[1]).."["..lua(t[2]).."]" + end + end, + -- SafeIndex{ expr expr } + SafeIndex = (t) + if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) + local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) + while t.tag == "SafeIndex" or t.tag == "SafeCall" do + table.insert(l, 1, t) + t = t[1] + end + local r = "(function()"..indent().."local "..var"safe".." = "..lua(l[1][1])..newline() -- base expr + for _, e in ipairs(l) do + r ..= "if "..var"safe".." == nil then return nil end"..newline() + if e.tag == "SafeIndex" then + r ..= var"safe".." = "..var"safe".."["..lua(e[2]).."]"..newline() + else + r ..= var"safe".." = "..var"safe".."("..lua(e, "_lhs", 2)..")"..newline() + end + end + r ..= "return "..var"safe"..unindent().."end)()" + return r + else -- no side effects possible + return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."["..lua(t[2]).."] or nil)" + end + end, + + -- opid -- + _opid = { + add = "+", sub = "-", mul = "*", div = "/", + idiv = "//", mod = "%", pow = "^", concat = "..", + band = "&", bor = "|", bxor = "~", shl = "<<", shr = ">>", + eq = "==", ne = "~=", lt = "<", gt = ">", le = "<=", ge = ">=", + ["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not" + } + }, { + __index = (self, key) + error("don't know how to compile a "..tostring(key).." to "..targetName) + end + }) + + #placeholder("patch") + + local code = lua(ast)..newline() + return requireStr..code +end From 73e3f95636a2e9aa1e02acb096b48d75daa1fd8e Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 24 Nov 2025 19:11:06 +0100 Subject: [PATCH 03/11] feat: implement global keyword in lua55 writer --- candran/can-parser/parser.lua | 26 ++++++++++++++++++-------- candran/can-parser/pp.lua | 4 ++-- candran/can-parser/validator.lua | 14 +++++++++++--- compiler/lua54.can | 10 ++++++++++ compiler/lua55.can | 21 +++++++++++++++++++++ 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/candran/can-parser/parser.lua b/candran/can-parser/parser.lua index 9964c08..615e006 100644 --- a/candran/can-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -1,5 +1,5 @@ --[[ -This module implements a parser for Lua 5.3 with LPeg, +This module implements a parser for Lua 5.5 with LPeg, and generates an Abstract Syntax Tree that is similar to the one generated by Metalua. For more information about Metalua, please, visit: https://github.com/fab13n/metalua-parser @@ -15,8 +15,11 @@ stat: | `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b end | `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end | `Local{ {attributeident+} {expr+}? } -- local i1, i2... = e1, e2... + | `Global{ {attributeident+} {expr+}? } -- global i1, i2... = e1, e2... | `Let{ {ident+} {expr+}? } -- let i1, i2... = e1, e2... | `Localrec{ {ident} {expr} } -- only used for 'local function' + | `Globalrec{ {ident} {expr} } -- only used for 'global function' + | `GlobalAll{ attribute? } -- only used for 'global *' | `Goto{ } -- goto str | `Label{ } -- ::str:: | `Return{ } -- return e1, e2... @@ -112,6 +115,7 @@ local labels = { { "ErrEListFor", "expected one or more expressions after 'in'" }, { "ErrDoFor", "expected 'do' after the range of the for loop" }, + { "ErrDefGlobal", "expected a function definition or assignment after global" }, { "ErrDefLocal", "expected a function definition or assignment after local" }, { "ErrDefLet", "expected an assignment after let" }, { "ErrDefClose", "expected an assignment after close" }, @@ -340,10 +344,10 @@ end local function searchEndRec (block, isRecCall) -- recursively search potential "end" keyword wrongly consumed by a short anonymous function on stat end (yeah, too late to change the syntax to something easier to parse) for i, stat in ipairs(block) do -- Non recursive statements - if stat.tag == "Set" or stat.tag == "Push" or stat.tag == "Return" or stat.tag == "Local" or stat.tag == "Let" or stat.tag == "Localrec" then + if stat.tag == "Set" or stat.tag == "Push" or stat.tag == "Return" or stat.tag == "Local" or stat.tag == "Let" or stat.tag == "Localrec" or stat.tag == "Global" or stat.tag == "Globalrec" then local exprlist - if stat.tag == "Set" or stat.tag == "Local" or stat.tag == "Let" or stat.tag == "Localrec" then + if stat.tag == "Set" or stat.tag == "Local" or stat.tag == "Let" or stat.tag == "Localrec" or stat.tag == "Global" or stat.tag == "Globalrec" then exprlist = stat[#stat] elseif stat.tag == "Push" or stat.tag == "Return" then exprlist = stat @@ -515,7 +519,7 @@ local G = { V"Lua", Block = tagC("Block", (V"Stat" + -V"BlockEnd" * throw("InvalidStat"))^0 * ((V"RetStat" + V"ImplicitPushStat") * sym(";")^-1)^-1); Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat" - + V"LocalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat" + + V"LocalStat" + V"GlobalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat" + V"LetStat" + V"ConstStat" + V"CloseStat" + V"FuncCall" + V"Assignment" + V"ContinueStat" + V"PushStat" @@ -542,6 +546,12 @@ local G = { V"Lua", ForIn = tagC("Forin", V"DestructuringNameList" * expect(kw("in"), "InFor") * expect(V"ExprList", "EListFor") * V"ForBody"); ForBody = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"); + GlobalStat = kw("global") * expect(V"GlobalFunc" + V"GlobalAssign", "DefGlobal"); + GlobalFunc = tagC("Globalrec", kw("function") * expect(V"Id", "NameLFunc") * V"FuncBody") / fixFuncStat; + GlobalAssign = tagC("Global", V"AttributeNameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + + tagC("Global", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")) + + tagC("GlobalAll", V "Attribute"^-1 * sym("*")), + LocalStat = kw("local") * expect(V"LocalFunc" + V"LocalAssign", "DefLocal"); LocalFunc = tagC("Localrec", kw("function") * expect(V"Id", "NameLFunc") * V"FuncBody") / fixFuncStat; LocalAssign = tagC("Local", V"AttributeNameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) @@ -551,9 +561,9 @@ local G = { V"Lua", LetAssign = tagC("Let", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + tagC("Let", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); - ConstStat = kw("const") * expect(V"AttributeAssign" / setAttribute("const"), "DefConst"); - CloseStat = kw("close") * expect(V"AttributeAssign" / setAttribute("close"), "DefClose"); - AttributeAssign = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + ConstStat = kw("const") * expect(V "LocalAssignNoAttribute" / setAttribute("const"), "DefConst"), + CloseStat = kw("close") * expect(V "LocalAssignNoAttribute" / setAttribute("close"), "DefClose"), + LocalAssignNoAttribute = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + tagC("Local", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); Assignment = tagC("Set", (V"VarList" + V"DestructuringNameList") * V"BinOp"^-1 * (P"=" / "=") * ((V"BinOp" - P"-") + #(P"-" * V"Space") * V"BinOp")^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); @@ -677,7 +687,7 @@ local G = { V"Lua", Reserved = V"Keywords" * -V"IdRest"; Keywords = P"and" + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" - + "local" + "nil" + "not" + "or" + "repeat" + "return" + + "local" + "global" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while"; Ident = V"IdStart" * V"IdRest"^0; IdStart = alpha + P"_"; diff --git a/candran/can-parser/pp.lua b/candran/can-parser/pp.lua index 649db38..744c107 100644 --- a/candran/can-parser/pp.lua +++ b/candran/can-parser/pp.lua @@ -245,7 +245,7 @@ function stm2str (stm) str = str .. explist2str(stm[2]) .. ", " str = str .. block2str(stm[3]) str = str .. " }" - elseif tag == "Local" then -- `Local{ {ident+} {expr+}? } + elseif tag == "Local" or tag == "Global" then -- `Local|Global{ {ident+} {expr+}? } str = str .. "{ " str = str .. varlist2str(stm[1]) if #stm[2] > 0 then @@ -254,7 +254,7 @@ function stm2str (stm) str = str .. ", " .. "{ }" end str = str .. " }" - elseif tag == "Localrec" then -- `Localrec{ ident expr } + elseif tag == "Localrec" or tag == "Globalrec" then -- `Localrec|Globalrec{ ident expr } str = str .. "{ " str = str .. "{ " .. var2str(stm[1][1]) .. " }, " str = str .. "{ " .. exp2str(stm[2][1]) .. " }" diff --git a/candran/can-parser/validator.lua b/candran/can-parser/validator.lua index ec15a63..6e7bd8d 100644 --- a/candran/can-parser/validator.lua +++ b/candran/can-parser/validator.lua @@ -1,5 +1,9 @@ --[[ -This module impements a validator for the AST +This module impements a validator for the AST. + +TODO/Checks that could be added in the future: +- Check if attributes are valid in declarations: in AttributeNameList, PrefixedAttributeNameList, and GlobalAll +- Check global variable declarations ]] local scope = require "candran.can-parser.scope" @@ -395,10 +399,14 @@ function traverse_stm (env, stm) elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } return traverse_forin(env, stm) elseif tag == "Local" or -- `Local{ {ident+} {expr+}? } - tag == "Let" then -- `Let{ {ident+} {expr+}? } + tag == "Let" or -- `Let{ {ident+} {expr+}? } + tag == "Global" then -- `Global{ {ident+} {expr+}? } return traverse_let(env, stm) - elseif tag == "Localrec" then -- `Localrec{ ident expr } + elseif tag == "Localrec" or -- `Localrec{ ident expr } + tag == "Globalrec" then -- `Globalrec{ ident expr } return traverse_letrec(env, stm) + elseif tag == "GlobalAll" then -- GlobalAll{ attribute? } + return true elseif tag == "Goto" then -- `Goto{ } return traverse_goto(env, stm) elseif tag == "Label" then -- `Label{ } diff --git a/compiler/lua54.can b/compiler/lua54.can index e9c6d98..e111df0 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -1,5 +1,15 @@ targetName = "Lua 5.4" +tags.Global = (t) + error("NYI") +end +tags.Globalrec = (t) + error("NYI") +end +tags.GlobalAll = (t) + error("NYI") +end + #placeholder("patch") #local patch = output diff --git a/compiler/lua55.can b/compiler/lua55.can index a55d1c7..08c87c8 100644 --- a/compiler/lua55.can +++ b/compiler/lua55.can @@ -471,6 +471,15 @@ return function(code, ast, options, macros={functions={}, variables={}}) end return r..DESTRUCTURING_ASSIGN(destructured) end, + -- Global{ {attributeident+} {expr+}? } + Global = (t) + local destructured = {} + local r = "global "..push("destructuring", destructured)..lua(t[1])..pop("destructuring") + if t[2][1] then + r ..= " = "..lua(t[2], "_lhs") + end + return r..DESTRUCTURING_ASSIGN(destructured) + end, -- Let{ {ident+} {expr+}? } Let = (t) local destructured = {} @@ -489,6 +498,18 @@ return function(code, ast, options, macros={functions={}, variables={}}) Localrec = (t) return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") end, + -- Globalrec{ {ident} {expr} } + Globalrec = (t) + return "global function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") + end, + -- GlobalAll{ attribute? } + GlobalAll = (t) + if #t == 1 then + return "global <" .. t[1] .. "> *" + else + return "global *" + end + end, -- Goto{ } Goto = (t) return "goto "..lua(t, "Id") From c5be1088c5bcb58592e3de23347cdb31be1ee644 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:12:33 +0100 Subject: [PATCH 04/11] feat: add named varargs from Lua 5.5 --- candran/can-parser/parser.lua | 6 ++-- candran/can-parser/validator.lua | 4 +-- compiler/lua55.can | 48 ++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/candran/can-parser/parser.lua b/candran/can-parser/parser.lua index 615e006..baf92f7 100644 --- a/candran/can-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -34,7 +34,7 @@ expr: | `Boolean{ } | `Number{ } -- we don't use convert to number to avoid losing precision when tostring()-ing it later | `String{ } - | `Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } + | `Function{ { ( `ParPair{ Id expr } | `Id{ } )* `ParDots? } block } | `Table{ ( `Pair{ expr expr } | expr )* } | `Op{ opid expr expr? } | `Paren{ expr } -- significant to cut multiple values returns @@ -573,8 +573,8 @@ local G = { V"Lua", * (sym(":") * expect(V"StrId", "NameFunc2"))^-1 / markMethod; FuncBody = tagC("Function", V"FuncParams" * expectBlockWithEnd("EndFunc")); FuncParams = expect(sym("("), "OParenPList") * V"ParList" * expect(sym(")"), "CParenPList"); - ParList = V"NamedParList" * (sym(",") * expect(tagC("Dots", sym("...")), "ParList"))^-1 / addDots - + Ct(tagC("Dots", sym("..."))) + ParList = V"NamedParList" * (sym(",") * expect(tagC("ParDots", sym("...") * V"Id"^-1), "ParList"))^-1 / addDots + + Ct(tagC("ParDots", sym("...") * V"Id"^-1)) + Ct(Cc()); -- Cc({}) generates a bug since the {} would be shared across parses ShortFuncDef = tagC("Function", V"ShortFuncParams" * maybeBlockWithEnd()) / fixShortFunc; diff --git a/candran/can-parser/validator.lua b/candran/can-parser/validator.lua index 6e7bd8d..c722003 100644 --- a/candran/can-parser/validator.lua +++ b/candran/can-parser/validator.lua @@ -71,7 +71,7 @@ local traverse_block, traverse_explist, traverse_varlist, traverse_parlist function traverse_parlist (env, parlist) local len = #parlist local is_vararg = false - if len > 0 and parlist[len].tag == "Dots" then + if len > 0 and parlist[len].tag == "ParDots" then is_vararg = true end set_vararg(env, is_vararg) @@ -348,7 +348,7 @@ function traverse_exp (env, exp) return true elseif tag == "Dots" then return traverse_vararg(env, exp) - elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } + elseif tag == "Function" then -- `Function{ { `Id{ }* `ParDots? } block } return traverse_function(env, exp) elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } return traverse_table(env, exp) diff --git a/compiler/lua55.can b/compiler/lua55.can index 08c87c8..add25c5 100644 --- a/compiler/lua55.can +++ b/compiler/lua55.can @@ -587,33 +587,35 @@ return function(code, ast, options, macros={functions={}, variables={}}) String = (t) return "%q":format(t[1]) end, - -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } + -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `ParDots? } block } + _functionParameter = { + ParPair = (t, decl) + local id = lua(t[1]) + indentLevel += 1 + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[2]).." end") + indentLevel -= 1 + return id + end, + ParDots = (t, decl) + if #t == 1 then + return "..." .. lua(t[1]) + else + return "..." + end + end, + }, _functionWithoutKeyword = (t) local r = "(" local decl = {} - if t[1][1] then - if t[1][1].tag == "ParPair" then - local id = lua(t[1][1][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") - indentLevel -= 1 - r ..= id + local pars = {} + for i=1, #t[1], 1 do + if tags._functionParameter[t[1][i].tag] then + table.insert(pars, tags._functionParameter[t[1][i].tag](t[1][i], decl)) else - r ..= lua(t[1][1]) - end - for i=2, #t[1], 1 do - if t[1][i].tag == "ParPair" then - local id = lua(t[1][i][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") - indentLevel -= 1 - r ..= ", " ..id - else - r ..= ", "..lua(t[1][i]) - end + table.insert(pars, lua(t[1][i])) end end - r ..= ")"..indent() + r ..= table.concat(pars, ", ")..")"..indent() for _, d in ipairs(decl) do r ..= d..newline() end @@ -851,6 +853,10 @@ return function(code, ast, options, macros={functions={}, variables={}}) AttributeNameList = (t) return lua(t, "_lhs") end, + -- NameList{ {Id+} } + NameList = (t) + return lua(t, "_lhs") + end, -- AttributeId{ ? } AttributeId = (t) if t[2] then From c13a7df27b7827b916bd9c432ed73df58d474478 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:13:07 +0100 Subject: [PATCH 05/11] feat: implement Lua5.5 -> Lua 5.4 compatibility --- compiler/lua54.can | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler/lua54.can b/compiler/lua54.can index e111df0..16650b0 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -1,13 +1,44 @@ targetName = "Lua 5.4" +-- Note: global declaration could be backported to older Lua versions, but would require more work than I personally have use for the feature; but if you have an use-case, open an issue and I'll give it a try. tags.Global = (t) - error("NYI") + error("target "..targetName.." does not support global variable declaration") end tags.Globalrec = (t) - error("NYI") + error("target "..targetName.." does not support global variable declaration") end tags.GlobalAll = (t) - error("NYI") + if #t == 1 then + error("target "..targetName.." does not support collective global variable declaration") + else + return "" -- global * is no-op when used alone + end +end + +-- Named vararg +tags._functionParameter.ParDots = (t, decl) + if #t == 1 then + local id = lua(t[1]) + indentLevel += 1 + table.insert(decl, "local "..id.." = { ... }") + indentLevel -= 1 + end + return "..." +end + +-- Prefixed attributes +-- PrefixedAttributeNameList{ attribute {AttributeId+} } +tags.PrefixedAttributeNameList = (t) + local ids = {} + for i=2, #t, 1 do + if t[i][2] then + error("target "..targetName.." does not support combining prefixed and suffixed attributes in variable declaration") + else + t[i][2] = t[1] + table.insert(ids, lua(t[i])) + end + end + return table.concat(ids, ", ") end #placeholder("patch") From f5d6a101eddd7135b8dfe3c5d05a9690cb66c22c Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:13:28 +0100 Subject: [PATCH 06/11] feat: add tests for Lua 5.4 & Lua 5.5 syntax additions --- compiler/lua55.can | 4 +- test/test.lua | 173 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 132 insertions(+), 45 deletions(-) diff --git a/compiler/lua55.can b/compiler/lua55.can index add25c5..e264a33 100644 --- a/compiler/lua55.can +++ b/compiler/lua55.can @@ -199,7 +199,7 @@ return function(code, ast, options, macros={functions={}, variables={}}) local CONTINUE_STOP = () -- at the start of loops using continue return unindent().."end"..newline().."::"..var"continue".."::" end - local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement + local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignment local vars = {} local values = {} for _, list in ipairs(destructured) do @@ -870,7 +870,7 @@ return function(code, ast, options, macros={functions={}, variables={}}) if t.id then -- destructing already done before, use parent variable as id return t.id else - local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") + local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") local vars = { id = tmp() } for j=1, #t, 1 do table.insert(vars, t[j]) diff --git a/test/test.lua b/test/test.lua index e01a4cf..30fc457 100644 --- a/test/test.lua +++ b/test/test.lua @@ -41,6 +41,11 @@ local function test(name, candranCode, expectedResult, options) results[name] = { result = "not finished", message = "no info" } local self = results[name] + -- result + if type(expectedResult) ~= "table" then + expectedResult = { "return", expectedResult } + end + -- options options = options or {} options.chunkname = name @@ -56,25 +61,33 @@ local function test(name, candranCode, expectedResult, options) -- load code local env = {} for k, v in pairs(_G) do env[k] = v end - local success, func = pcall(load, code, nil, env) - if not success then + local func, err = load(code, name, env) + if err then + if expectedResult[1] == "loadError" and err:match(expectedResult[2] or "") then + self.result = "success" + return + end self.result = "error" - self.message = c("/!\\ error while loading code:\n"..func.."\ngenerated code:\n", "bold", "red")..c(code, "red") + self.message = c("/!\\ error while loading code:\n"..err.."\ngenerated code:\n", "bold", "red")..c(code, "red") return end -- run code local success, output = pcall(func) if not success then + if expectedResult[1] == "runtimeError" and output:match(expectedResult[2] or "") then + self.result = "success" + return + end self.result = "error" self.message = c("/!\\ error while running code:\n"..output.."\ngenerated code:\n", "bold", "red")..c(code, "red") return end -- check result - if output ~= expectedResult then + if expectedResult[1] == "return" and output ~= expectedResult[2] then self.result = "fail" - self.message = c("/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult).."; generated code:\n", "bold", "purple")..c(code, "purple") + self.message = c("/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult[2]).."; generated code:\n", "bold", "purple")..c(code, "purple") return else self.result = "success" @@ -214,7 +227,7 @@ return hello -- SYNTAX ADDITIONS -- ---------------------- --- Assignement operators +-- Assignment operators test("+=", [[ local a = 5 a += 2 @@ -286,7 +299,7 @@ test(">>=", [[ return a ]], 5) -test("right assigments operators", [[ +test("right assignments operators", [[ local a = 5 a =+ 2 assert(a == 7, "=+") a =- 2 assert(a == -5, "=-") @@ -312,7 +325,7 @@ test("right assigments operators", [[ a =>> 23 assert(a == 5, "=>>") ]], nil) -test("some left+right assigments operators", [[ +test("some left+right assignments operators", [[ local a = 5 a -=+ 2 assert(a == 8, "-=+") @@ -320,17 +333,17 @@ test("some left+right assigments operators", [[ a ..=.. " world " assert(a == "hello world hello", "..=..") ]], nil) -test("left assigments operators priority", [[ +test("left assignments operators priority", [[ local a = 5 a *= 2 + 3 return a ]], 25) -test("right assigments operators priority", [[ +test("right assignments operators priority", [[ local a = 5 a =/ 2 + 3 return a ]], 1) -test("left+right assigments operators priority", [[ +test("left+right assignments operators priority", [[ local a = 5 a *=/ 2 + 3 return a @@ -915,63 +928,63 @@ test("safe prefixes, random chaining", [[ assert(f.l?:o?() == nil) ]]) --- Destructuring assigments -test("destructuring assignement with an expression", [[ +-- Destructuring assignments +test("destructuring assignment with an expression", [[ local {x, y} = { x = 5, y = 1 } return x + y ]], 6) -test("destructuring assignement with local", [[ +test("destructuring assignment with local", [[ t = { x = 5, y = 1 } local {x, y} = t return x + y ]], 6) -test("destructuring assignement", [[ +test("destructuring assignment", [[ t = { x = 5, y = 1 } {x, y} = t return x + y ]], 6) -test("destructuring assignement with +=", [[ +test("destructuring assignment with +=", [[ t = { x = 5, y = 1 } local x, y = 5, 9 {x, y} += t return x + y ]], 20) -test("destructuring assignement with =-", [[ +test("destructuring assignment with =-", [[ t = { x = 5, y = 1 } local x, y = 5, 9 {x, y} =- t return x + y ]], -8) -test("destructuring assignement with +=-", [[ +test("destructuring assignment with +=-", [[ t = { x = 5, y = 1 } local x, y = 5, 9 {x, y} +=- t return x + y ]], 6) -test("destructuring assignement with =-", [[ +test("destructuring assignment with =-", [[ t = { x = 5, y = 1 } local x, y = 5, 9 {x, y} =- t return x + y ]], -8) -test("destructuring assignement with let", [[ +test("destructuring assignment with let", [[ t = { x = 5, y = 1 } let {x, y} = t return x + y ]], 6) -test("destructuring assignement with for in", [[ +test("destructuring assignment with for in", [[ t = {{ x = 5, y = 1 }} for k, {x, y} in pairs(t) do return x + y end ]], 6) -test("destructuring assignement with if with assignement", [[ +test("destructuring assignment with if with assignment", [[ t = { x = 5, y = 1 } if {x, y} = t then return x + y end ]], 6) -test("destructuring assignement with if-elseif with assignement", [[ +test("destructuring assignment with if-elseif with assignment", [[ t = { x = 5, y = 1 } if ({u} = t) and u then return 0 @@ -980,56 +993,56 @@ test("destructuring assignement with if-elseif with assignement", [[ end ]], 6) -test("destructuring assignement with an expression with custom name", [[ +test("destructuring assignment with an expression with custom name", [[ local {o = x, y} = { o = 5, y = 1 } return x + y ]], 6) -test("destructuring assignement with local with custom name", [[ +test("destructuring assignment with local with custom name", [[ t = { o = 5, y = 1 } local {o = x, y} = t return x + y ]], 6) -test("destructuring assignement with custom name", [[ +test("destructuring assignment with custom name", [[ t = { o = 5, y = 1 } {o = x, y} = t return x + y ]], 6) -test("destructuring assignement with += with custom name", [[ +test("destructuring assignment with += with custom name", [[ t = { o = 5, y = 1 } local x, y = 5, 9 {o = x, y} += t return x + y ]], 20) -test("destructuring assignement with =- with custom name", [[ +test("destructuring assignment with =- with custom name", [[ t = { o = 5, y = 1 } local x, y = 5, 9 {o = x, y} =- t return x + y ]], -8) -test("destructuring assignement with +=- with custom name", [[ +test("destructuring assignment with +=- with custom name", [[ t = { o = 5, y = 1 } local x, y = 5, 9 {o = x, y} +=- t return x + y ]], 6) -test("destructuring assignement with let with custom name", [[ +test("destructuring assignment with let with custom name", [[ t = { o = 5, y = 1 } let {o = x, y} = t return x + y ]], 6) -test("destructuring assignement with for in with custom name", [[ +test("destructuring assignment with for in with custom name", [[ t = {{ o = 5, y = 1 }} for k, {o = x, y} in pairs(t) do return x + y end ]], 6) -test("destructuring assignement with if with assignement with custom name", [[ +test("destructuring assignment with if with assignment with custom name", [[ t = { o = 5, y = 1 } if {o = x, y} = t then return x + y end ]], 6) -test("destructuring assignement with if-elseif with assignement with custom name", [[ +test("destructuring assignment with if-elseif with assignment with custom name", [[ t = { o = 5, y = 1 } if ({x} = t) and x then return 0 @@ -1038,56 +1051,56 @@ test("destructuring assignement with if-elseif with assignement with custom name end ]], 6) -test("destructuring assignement with an expression with expression as key", [[ +test("destructuring assignment with an expression with expression as key", [[ local {[1] = x, y} = { 5, y = 1 } return x + y ]], 6) -test("destructuring assignement with local with expression as key", [[ +test("destructuring assignment with local with expression as key", [[ t = { 5, y = 1 } local {[1] = x, y} = t return x + y ]], 6) -test("destructuring assignement with expression as key", [[ +test("destructuring assignment with expression as key", [[ t = { 5, y = 1 } {[1] = x, y} = t return x + y ]], 6) -test("destructuring assignement with += with expression as key", [[ +test("destructuring assignment with += with expression as key", [[ t = { 5, y = 1 } local x, y = 5, 9 {[1] = x, y} += t return x + y ]], 20) -test("destructuring assignement with =- with expression as key", [[ +test("destructuring assignment with =- with expression as key", [[ t = { 5, y = 1 } local x, y = 5, 9 {[1] = x, y} =- t return x + y ]], -8) -test("destructuring assignement with +=- with expression as key", [[ +test("destructuring assignment with +=- with expression as key", [[ t = { 5, y = 1 } local x, y = 5, 9 {[1] = x, y} +=- t return x + y ]], 6) -test("destructuring assignement with let with expression as key", [[ +test("destructuring assignment with let with expression as key", [[ t = { 5, y = 1 } let {[1] = x, y} = t return x + y ]], 6) -test("destructuring assignement with for in with expression as key", [[ +test("destructuring assignment with for in with expression as key", [[ t = {{ 5, y = 1 }} for k, {[1] = x, y} in pairs(t) do return x + y end ]], 6) -test("destructuring assignement with if with assignement with expression as key", [[ +test("destructuring assignment with if with assignment with expression as key", [[ t = { 5, y = 1 } if {[1] = x, y} = t then return x + y end ]], 6) -test("destructuring assignement with if-elseif with assignement with expression as key", [[ +test("destructuring assignment with if-elseif with assignment with expression as key", [[ t = { 5, y = 1 } if ({x} = t) and x then return 0 @@ -1096,6 +1109,80 @@ test("destructuring assignement with if-elseif with assignement with expression end ]], 6) +-- named varargs +test("named varargs", [[ + function fn(...x) + return table.concat(x, "-") + end + return fn("hello", "world") +]], "hello-world") +test("named varargs with preceding arguments", [[ + function fn(a, ...x) + return a..table.concat(x, "-") + end + return fn("hey! ", "hello", "world") +]], "hey! hello-world") + +-- variable attributes +if _VERSION >= "Lua 5.4" then + test("variable attributes", [[ + local a , b, c + b = 42 + ]]) + + test("variable attributes: const violation", [[ + local a , b, c + b = 42 + a = 42 + ]], { "loadError", "attempt to assign to const variable 'a'" }) + + test("variable attributes: const violation 2", [[ + local d, e, f + e = 42 + ]], { "loadError", "attempt to assign to const variable 'e'" }) + + test("variable attributes shortcut", [[ + const a + a = 42 + ]], { "loadError", "attempt to assign to const variable 'a'" }) +end + +-- global keyword +test("collective global variable declaration", [[ +foo = 42 +do + global * +end +foo = 12 +]]) +if _VERSION >= "Lua 5.5" then + test("global variable declaration", [[ + do + global foo + global bar + end + foo = 42 + assert(not pcall(function() foo = 42 end)) + ]]) + test("collective global variable declaration with attribute", [[ + foo = 42 + do + global * + end + assert(not pcall(function() foo = 12 end)) + ]]) +end + +-- bitwise operators +if _VERSION >= "Lua 5.2" or bit then + test("bitwise operators: &", "return 0xDEAD & 0xBEEF", 40621) + test("bitwise operators: |", "return 0xDEAD | 0xBEEF", 65263) + test("bitwise operators: ~", "return 0xDEAD ~ 0xBEEF", 24642) + test("bitwise operators: >>", "return 0xDEAD >> 2", 14251) + test("bitwise operators: <<", "return 0xDEAD << 2", 228020) + test("bitwise operators: unary ~", "return ~0xDEAD", -57006) +end + -- results local resultCounter = {} local testCounter = 0 From 523fdc6678d8e12f5d319613e4337d33d3c81a7f Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:14:23 +0100 Subject: [PATCH 07/11] docs: update README for Lua 5.5 --- README.md | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c708f6b..ac241ea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Candran ======= -Candran is a dialect of the [Lua 5.4](http://www.lua.org) programming language which compiles to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. +Candran is a dialect of the [Lua 5.5](http://www.lua.org) programming language which compiles to Lua 5.5, Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. @@ -51,7 +51,7 @@ end) a.child?:method?() -- safe navigation operator -local {hey, method} = a -- destructuring assignement +local {hey, method} = a -- destructuring assignment local odd = [ -- table comprehension for i=1, 10 do @@ -66,9 +66,9 @@ local count = [for i=1,10 i] -- single line statements local a = if condition then "one" else "two" end -- statement as expressions -print("Hello %s":format("world")) -- methods calls on strings (and tables) litterals without enclosing parentheses +print("Hello %s":format("world")) -- methods calls on strings (and tables) literals without enclosing parentheses -if f, err = io.open("data") then -- if condition with assignements +if f, err = io.open("data") then -- if condition with assignments thing.process(f) else error("can't open data: "..err) @@ -104,7 +104,7 @@ For linting, if your editor support [luacheck](https://github.com/luarocks/luach The language ------------ ### Syntax additions -After the [preprocessor](#preprocessor) is run the Candran code is compiled to Lua. Candran code adds the folowing syntax to Lua 5.4 syntax: +After the [preprocessor](#preprocessor) is run the Candran code is compiled to Lua. Candran code adds the folowing syntax to standard Lua syntax: ##### Assignment operators * ````var += nb```` @@ -124,7 +124,7 @@ After the [preprocessor](#preprocessor) is run the Candran code is compiled to L For example, a ````var += nb```` assignment will be compiled into ````var = var + nb````. -All theses operators can also be put right of the assigment operator, in which case ```var =+ nb``` will be compiled into ```var = nb + var```. +All theses operators can also be put right of the assignment operator, in which case ```var =+ nb``` will be compiled into ```var = nb + var```. Right and left operator can be used at the same time. @@ -273,7 +273,7 @@ Values returned by the function will be inserted in the generated table in the o The table generation function also have access to the `self` variable (and its alias `@`), which is the table which is being created, so you can set any of the table's field. -##### Destructuring assignement +##### Destructuring assignment ```lua t = { x = 1, y = 2, z = 3 } @@ -283,21 +283,21 @@ t = { x = 1, y = 2, z = 3 } {["x"] = o} = t -- o = t["x"] --- Also works with local, let, for ... in, if with assignement, +=, etc. +-- Also works with local, let, for ... in, if with assignment, +=, etc. local {x, y} = t let {x, y} = t for i, {x, y} in ipairs{t} do end if {x, y} = t then end {x} += t -- x = x + t.x --- Works as expected with multiple assignement. +-- Works as expected with multiple assignment. a, {x, y, z}, b = 1, t, 2 ``` -Destruturing assignement allows to quickly extract fields from a table into a variable. +Destruturing assignment allows to quickly extract fields from a table into a variable. -This is done by replacing the variable name in any assignement with a table literal, where every item is the name of the field and assigned variable. It is possible to use a different field name than the variable name by naming the table item (`fieldName = var` or `[fieldExpression] = var`). +This is done by replacing the variable name in any assignment with a table literal, where every item is the name of the field and assigned variable. It is possible to use a different field name than the variable name by naming the table item (`fieldName = var` or `[fieldExpression] = var`). ##### Safe navigation operators @@ -328,7 +328,7 @@ print(a?()) -- nil if a is nil, other normal behaviour Some operators can be prefixed by a `?` to turn into a safe version of the operator: if the base value if `nil`, the normal behaviour of the operator will be skipped and nil will be returned; otherwise, the operator run as usual. Is available safe dot index `?.`, safe array index `?[...]`, safe method stub `?:` and safe function call `?(...)`. -##### If and while with assignement in the condition +##### If and while with assignment in the condition ```lua if f, err = io.open("somefile") then -- condition if verified if f is a truthy value (not nil or false) -- do something with f @@ -343,7 +343,7 @@ else end -- f, err, f2 and err2 are now out of scope -if (value = list[index = 2]) and yes = true then -- several assignements can be performed, anywhere in the expression; index is defined before value, yes is defined after these two. The condition is verified if both value and yes are thruthy. +if (value = list[index = 2]) and yes = true then -- several assignments can be performed, anywhere in the expression; index is defined before value, yes is defined after these two. The condition is verified if both value and yes are thruthy. print(index, value) end @@ -352,13 +352,13 @@ while line = io.read() do print(line) end --- The assignement have the same priority as regular assignements, i.e., the lowest. +-- The assignment have the same priority as regular assignments, i.e., the lowest. if a = 1 and 2 then -- will be read as a = (1 and 2) elseif (a = 1) and 2 then -- will be read as (a = 1) and 2 end ``` -Assignements can be used in the condition of if, elseif and while statements. Several variables can be assigned; only the first will be tested in the condition, for each assignement. The assigned variables will be in scope the duration of the block; for if statements, they will also be in scope for the following elseif(s) and else. +Assignments can be used in the condition of if, elseif and while statements. Several variables can be assigned; only the first will be tested in the condition, for each assignment. The assigned variables will be in scope the duration of the block; for if statements, they will also be in scope for the following elseif(s) and else. For while statements, the assigned expression will be reevaluated at each iteration. @@ -498,19 +498,22 @@ You can disable these built-in macros using the `builtInMacros` compiler option. Compile targets --------------- -Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT, and Lua 5.1 compatible code. +Candran is based on the Lua 5.5 syntax, but can be compiled to Lua 5.5, Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT, and Lua 5.1 compatible code. -To chose a compile target, set the ```target``` option to ```lua54```, ```lua53```, ```lua52```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. +To chose a compile target, set the ```target``` option to ```lua55```, ```lua54```, ```lua53```, ```lua52```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. -Candran will try to translate Lua 5.4 syntax into something usable with the current target if possible. Here is what is currently supported: +Candran will try to translate Lua 5.5 syntax into something usable with the current target if possible. Some syntax features are only supported by specific targets: -| Lua version | Candran target | Integer division operator // | Bitwise operators | Goto/Labels | Variable attributes | -| --- | --- | --- | --- | --- | --- | -| Lua 5.4 | lua54 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Lua 5.3 | lua53 | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | -| Lua 5.2 | lua52 | :white_check_mark: | :white_check_mark: (32bit) | :white_check_mark: | X | -| LuaJIT | luajit | :white_check_mark: | :white_check_mark: (32bit) | :white_check_mark: | X | -| Lua 5.1 | lua51 | :white_check_mark: | :white_check_mark: if LuaJIT bit library is available (32bit) | X | X | +| Lua version | Candran target | Bitwise operators | Goto/Labels | Variable attributes | Global keyword | +| --- | --- | --- | --- | --- | --- | +| Lua 5.5 | lua55 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Lua 5.4 | lua54 | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | +| Lua 5.3 | lua53 | :white_check_mark: | :white_check_mark: | X | X | +| Lua 5.2 | lua52 | :white_check_mark: (32bit) | :white_check_mark: | X | X | +| LuaJIT | luajit | :white_check_mark: (32bit) | :white_check_mark: | X | X | +| Lua 5.1 | lua51 | :white_check_mark: if LuaJIT bit library is available (32bit) | X | X | X | + +All other Lua 5.5 syntax features not listed in this table, like the integer division operator `//`, named varargs, are supported by all targets. **Please note** that Candran only translates syntax, and will not try to do anything about changes in the Lua standard library (for example, the new utf8 module). If you need this, you should be able to use [lua-compat-5.3](https://github.com/keplerproject/lua-compat-5.3) along with Candran. @@ -684,7 +687,7 @@ at the top of your main Lua file. If a Candran file is found when you call ```re You can give arbitrary options to the compiler and preprocessor, but Candran already provide and uses these with their associated default values: ```lua -target = "lua53" -- compiler target. "lua54", "lua53", "lua52", "luajit" or "lua51" (default is automatically selected based on the Lua version used). +target = "lua55" -- compiler target. "lua55", "lua54", "lua53", "lua52", "luajit" or "lua51" (default is automatically selected based on the Lua version used). indentation = "" -- character(s) used for indentation in the compiled file. newline = "\n" -- character(s) used for newlines in the compiled file. variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local variable to provide some functionality (example: to load LuaJIT's bit lib when using bitwise operators). From 15c4ebe701831f068e75903ac986a6f629be3e1a Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:14:52 +0100 Subject: [PATCH 08/11] chore: recompile candran --- candran.lua | 13614 +++++++++++++++++++++++++++----------------------- 1 file changed, 7470 insertions(+), 6144 deletions(-) diff --git a/candran.lua b/candran.lua index f3945ad..18004eb 100644 --- a/candran.lua +++ b/candran.lua @@ -358,1868 +358,2964 @@ end -- ./candran/serpent.lua:163 local serpent = _() or serpent -- ./candran/serpent.lua:167 package["loaded"]["candran.serpent"] = serpent or true -- ./candran/serpent.lua:168 local function _() -- ./candran/serpent.lua:172 -local util = require("candran.util") -- ./compiler/lua54.can:1 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 -return function(code, ast, options, macros) -- ./compiler/lua54.can:7 -if macros == nil then macros = { -- ./compiler/lua54.can:7 -["functions"] = {}, -- ./compiler/lua54.can:7 -["variables"] = {} -- ./compiler/lua54.can:7 -} end -- ./compiler/lua54.can:7 -local lastInputPos = 1 -- ./compiler/lua54.can:9 -local prevLinePos = 1 -- ./compiler/lua54.can:10 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 -local lastLine = 1 -- ./compiler/lua54.can:12 -local indentLevel = 0 -- ./compiler/lua54.can:15 -local function newline() -- ./compiler/lua54.can:17 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 -if options["mapLines"] then -- ./compiler/lua54.can:19 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:21 -if source and line then -- ./compiler/lua54.can:23 -lastSource = source -- ./compiler/lua54.can:24 -lastLine = tonumber(line) -- ./compiler/lua54.can:25 -else -- ./compiler/lua54.can:25 +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:27 -lastLine = lastLine + (1) -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -prevLinePos = lastInputPos -- ./compiler/lua54.can:32 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 -end -- ./compiler/lua54.can:34 -return r -- ./compiler/lua54.can:36 -end -- ./compiler/lua54.can:36 -local function indent() -- ./compiler/lua54.can:39 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 -return newline() -- ./compiler/lua54.can:41 -end -- ./compiler/lua54.can:41 -local function unindent() -- ./compiler/lua54.can:44 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 -return newline() -- ./compiler/lua54.can:46 -end -- ./compiler/lua54.can:46 -local states = { -- ./compiler/lua54.can:51 -["push"] = {}, -- ./compiler/lua54.can:52 -["destructuring"] = {}, -- ./compiler/lua54.can:53 -["scope"] = {}, -- ./compiler/lua54.can:54 -["macroargs"] = {} -- ./compiler/lua54.can:55 -} -- ./compiler/lua54.can:55 -local function push(name, state) -- ./compiler/lua54.can:58 -table["insert"](states[name], state) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function pop(name) -- ./compiler/lua54.can:63 -table["remove"](states[name]) -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function set(name, state) -- ./compiler/lua54.can:68 -states[name][# states[name]] = state -- ./compiler/lua54.can:69 -return "" -- ./compiler/lua54.can:70 -end -- ./compiler/lua54.can:70 -local function peek(name) -- ./compiler/lua54.can:73 -return states[name][# states[name]] -- ./compiler/lua54.can:74 -end -- ./compiler/lua54.can:74 -local function var(name) -- ./compiler/lua54.can:79 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 -end -- ./compiler/lua54.can:80 -local function tmp() -- ./compiler/lua54.can:84 -local scope = peek("scope") -- ./compiler/lua54.can:85 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 -table["insert"](scope, var) -- ./compiler/lua54.can:87 -return var -- ./compiler/lua54.can:88 -end -- ./compiler/lua54.can:88 -local nomacro = { -- ./compiler/lua54.can:92 -["variables"] = {}, -- ./compiler/lua54.can:92 -["functions"] = {} -- ./compiler/lua54.can:92 -} -- ./compiler/lua54.can:92 -local required = {} -- ./compiler/lua54.can:95 -local requireStr = "" -- ./compiler/lua54.can:96 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 -if not required[req] then -- ./compiler/lua54.can:100 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 -required[req] = true -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -local loop = { -- ./compiler/lua54.can:107 -"While", -- ./compiler/lua54.can:107 -"Repeat", -- ./compiler/lua54.can:107 -"Fornum", -- ./compiler/lua54.can:107 -"Forin", -- ./compiler/lua54.can:107 -"WhileExpr", -- ./compiler/lua54.can:107 -"RepeatExpr", -- ./compiler/lua54.can:107 -"FornumExpr", -- ./compiler/lua54.can:107 -"ForinExpr" -- ./compiler/lua54.can:107 -} -- ./compiler/lua54.can:107 -local func = { -- ./compiler/lua54.can:108 -"Function", -- ./compiler/lua54.can:108 -"TableCompr", -- ./compiler/lua54.can:108 -"DoExpr", -- ./compiler/lua54.can:108 -"WhileExpr", -- ./compiler/lua54.can:108 -"RepeatExpr", -- ./compiler/lua54.can:108 -"IfExpr", -- ./compiler/lua54.can:108 -"FornumExpr", -- ./compiler/lua54.can:108 -"ForinExpr" -- ./compiler/lua54.can:108 -} -- ./compiler/lua54.can:108 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 -local tagsCheck = {} -- ./compiler/lua54.can:113 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 -tagsCheck[tag] = true -- ./compiler/lua54.can:115 -end -- ./compiler/lua54.can:115 -local nofollowCheck = {} -- ./compiler/lua54.can:117 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 -nofollowCheck[tag] = true -- ./compiler/lua54.can:119 -end -- ./compiler/lua54.can:119 -for _, node in ipairs(list) do -- ./compiler/lua54.can:121 -if type(node) == "table" then -- ./compiler/lua54.can:122 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 -return node -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 -if r then -- ./compiler/lua54.can:128 -return r -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -return nil -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 -local tagsCheck = {} -- ./compiler/lua54.can:138 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 -tagsCheck[tag] = true -- ./compiler/lua54.can:140 -end -- ./compiler/lua54.can:140 -local nofollowCheck = {} -- ./compiler/lua54.can:142 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 -nofollowCheck[tag] = true -- ./compiler/lua54.can:144 -end -- ./compiler/lua54.can:144 -local found = {} -- ./compiler/lua54.can:146 -for _, node in ipairs(list) do -- ./compiler/lua54.can:147 -if type(node) == "table" then -- ./compiler/lua54.can:148 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 -table["insert"](found, n) -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 -table["insert"](found, node) -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -return found -- ./compiler/lua54.can:159 -end -- ./compiler/lua54.can:159 -local function all(list, tags) -- ./compiler/lua54.can:163 -for _, node in ipairs(list) do -- ./compiler/lua54.can:164 -local ok = false -- ./compiler/lua54.can:165 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 -if node["tag"] == tag then -- ./compiler/lua54.can:167 -ok = true -- ./compiler/lua54.can:168 -break -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -if not ok then -- ./compiler/lua54.can:172 -return false -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -return true -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -local tags -- ./compiler/lua54.can:180 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 -end -- ./compiler/lua54.can:184 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 -end -- ./compiler/lua54.can:191 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 -end -- ./compiler/lua54.can:194 -local CONTINUE_START = function() -- ./compiler/lua54.can:196 -return "do" .. indent() -- ./compiler/lua54.can:197 -end -- ./compiler/lua54.can:197 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 -end -- ./compiler/lua54.can:200 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 -local vars = {} -- ./compiler/lua54.can:203 -local values = {} -- ./compiler/lua54.can:204 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 -for _, v in ipairs(list) do -- ./compiler/lua54.can:206 -local var, val -- ./compiler/lua54.can:207 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 -var = v -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Index", -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Id", -- ./compiler/lua54.can:210 -list["id"] -- ./compiler/lua54.can:210 -}, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "String", -- ./compiler/lua54.can:210 -v[1] -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 -var = v[2] -- ./compiler/lua54.can:212 -val = { -- ./compiler/lua54.can:213 -["tag"] = "Index", -- ./compiler/lua54.can:213 -{ -- ./compiler/lua54.can:213 -["tag"] = "Id", -- ./compiler/lua54.can:213 -list["id"] -- ./compiler/lua54.can:213 -}, -- ./compiler/lua54.can:213 -v[1] -- ./compiler/lua54.can:213 -} -- ./compiler/lua54.can:213 -else -- ./compiler/lua54.can:213 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 -end -- ./compiler/lua54.can:215 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 -val = { -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["rightOp"], -- ./compiler/lua54.can:218 -var, -- ./compiler/lua54.can:218 -{ -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["leftOp"], -- ./compiler/lua54.can:218 -val, -- ./compiler/lua54.can:218 -var -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 -val = { -- ./compiler/lua54.can:220 -["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["rightOp"], -- ./compiler/lua54.can:220 -var, -- ./compiler/lua54.can:220 -val -- ./compiler/lua54.can:220 -} -- ./compiler/lua54.can:220 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 -val = { -- ./compiler/lua54.can:222 -["tag"] = "Op", -- ./compiler/lua54.can:222 -destructured["leftOp"], -- ./compiler/lua54.can:222 -val, -- ./compiler/lua54.can:222 -var -- ./compiler/lua54.can:222 -} -- ./compiler/lua54.can:222 -end -- ./compiler/lua54.can:222 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -if # vars > 0 then -- ./compiler/lua54.can:228 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 -if newlineAfter then -- ./compiler/lua54.can:230 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 -else -- ./compiler/lua54.can:231 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 -end -- ./compiler/lua54.can:233 -else -- ./compiler/lua54.can:233 -return "" -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -tags = setmetatable({ -- ./compiler/lua54.can:241 -["Block"] = function(t) -- ./compiler/lua54.can:243 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 -hasPush = false -- ./compiler/lua54.can:247 -end -- ./compiler/lua54.can:247 -local r = push("scope", {}) -- ./compiler/lua54.can:249 -if hasPush then -- ./compiler/lua54.can:250 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 -end -- ./compiler/lua54.can:251 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 -end -- ./compiler/lua54.can:254 -if t[# t] then -- ./compiler/lua54.can:256 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 -end -- ./compiler/lua54.can:257 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 -end -- ./compiler/lua54.can:260 -return r .. pop("scope") -- ./compiler/lua54.can:262 -end, -- ./compiler/lua54.can:262 -["Do"] = function(t) -- ./compiler/lua54.can:268 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 -end, -- ./compiler/lua54.can:269 -["Set"] = function(t) -- ./compiler/lua54.can:272 -local expr = t[# t] -- ./compiler/lua54.can:274 -local vars, values = {}, {} -- ./compiler/lua54.can:275 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 -else -- ./compiler/lua54.can:280 -table["insert"](vars, n) -- ./compiler/lua54.can:282 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 -local r = "" -- ./compiler/lua54.can:288 -if # vars > 0 then -- ./compiler/lua54.can:289 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 -end -- ./compiler/lua54.can:290 -if # destructuringVars > 0 then -- ./compiler/lua54.can:292 -local destructured = {} -- ./compiler/lua54.can:293 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 -end -- ./compiler/lua54.can:295 -return r -- ./compiler/lua54.can:297 -elseif # t == 4 then -- ./compiler/lua54.can:298 -if t[3] == "=" then -- ./compiler/lua54.can:299 -local r = "" -- ./compiler/lua54.can:300 -if # vars > 0 then -- ./compiler/lua54.can:301 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 -t[2], -- ./compiler/lua54.can:302 -vars[1], -- ./compiler/lua54.can:302 -{ -- ./compiler/lua54.can:302 -["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[1] -- ./compiler/lua54.can:302 -} -- ./compiler/lua54.can:302 -}, "Op")) -- ./compiler/lua54.can:302 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 -t[2], -- ./compiler/lua54.can:304 -vars[i], -- ./compiler/lua54.can:304 -{ -- ./compiler/lua54.can:304 -["tag"] = "Paren", -- ./compiler/lua54.can:304 -values[i] -- ./compiler/lua54.can:304 -} -- ./compiler/lua54.can:304 -}, "Op")) -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -if # destructuringVars > 0 then -- ./compiler/lua54.can:307 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -return r -- ./compiler/lua54.can:312 -else -- ./compiler/lua54.can:312 -local r = "" -- ./compiler/lua54.can:314 -if # vars > 0 then -- ./compiler/lua54.can:315 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 -t[3], -- ./compiler/lua54.can:316 -{ -- ./compiler/lua54.can:316 -["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[1] -- ./compiler/lua54.can:316 -}, -- ./compiler/lua54.can:316 -vars[1] -- ./compiler/lua54.can:316 -}, "Op")) -- ./compiler/lua54.can:316 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 -t[3], -- ./compiler/lua54.can:318 -{ -- ./compiler/lua54.can:318 -["tag"] = "Paren", -- ./compiler/lua54.can:318 -values[i] -- ./compiler/lua54.can:318 -}, -- ./compiler/lua54.can:318 -vars[i] -- ./compiler/lua54.can:318 -}, "Op")) -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -if # destructuringVars > 0 then -- ./compiler/lua54.can:321 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 -end -- ./compiler/lua54.can:324 -return r -- ./compiler/lua54.can:326 -end -- ./compiler/lua54.can:326 -else -- ./compiler/lua54.can:326 -local r = "" -- ./compiler/lua54.can:329 -if # vars > 0 then -- ./compiler/lua54.can:330 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 -t[2], -- ./compiler/lua54.can:331 -vars[1], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Op", -- ./compiler/lua54.can:331 -t[4], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[1] -- ./compiler/lua54.can:331 -}, -- ./compiler/lua54.can:331 -vars[1] -- ./compiler/lua54.can:331 -} -- ./compiler/lua54.can:331 -}, "Op")) -- ./compiler/lua54.can:331 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 -t[2], -- ./compiler/lua54.can:333 -vars[i], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Op", -- ./compiler/lua54.can:333 -t[4], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Paren", -- ./compiler/lua54.can:333 -values[i] -- ./compiler/lua54.can:333 -}, -- ./compiler/lua54.can:333 -vars[i] -- ./compiler/lua54.can:333 -} -- ./compiler/lua54.can:333 -}, "Op")) -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -if # destructuringVars > 0 then -- ./compiler/lua54.can:336 -local destructured = { -- ./compiler/lua54.can:337 -["rightOp"] = t[2], -- ./compiler/lua54.can:337 -["leftOp"] = t[4] -- ./compiler/lua54.can:337 -} -- ./compiler/lua54.can:337 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 -end -- ./compiler/lua54.can:339 -return r -- ./compiler/lua54.can:341 -end -- ./compiler/lua54.can:341 -end, -- ./compiler/lua54.can:341 -["While"] = function(t) -- ./compiler/lua54.can:345 -local r = "" -- ./compiler/lua54.can:346 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 -if # lets > 0 then -- ./compiler/lua54.can:349 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 -if # lets > 0 then -- ./compiler/lua54.can:356 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 -end -- ./compiler/lua54.can:357 -if hasContinue then -- ./compiler/lua54.can:359 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 -end -- ./compiler/lua54.can:360 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 -if hasContinue then -- ./compiler/lua54.can:363 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 -end -- ./compiler/lua54.can:364 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 -if # lets > 0 then -- ./compiler/lua54.can:367 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 -end -- ./compiler/lua54.can:369 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 -end -- ./compiler/lua54.can:371 -return r -- ./compiler/lua54.can:373 -end, -- ./compiler/lua54.can:373 -["Repeat"] = function(t) -- ./compiler/lua54.can:376 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 -local r = "repeat" .. indent() -- ./compiler/lua54.can:378 -if hasContinue then -- ./compiler/lua54.can:379 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 -end -- ./compiler/lua54.can:380 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 -if hasContinue then -- ./compiler/lua54.can:383 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 -end -- ./compiler/lua54.can:384 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 -return r -- ./compiler/lua54.can:387 -end, -- ./compiler/lua54.can:387 -["If"] = function(t) -- ./compiler/lua54.can:390 -local r = "" -- ./compiler/lua54.can:391 -local toClose = 0 -- ./compiler/lua54.can:392 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 -if # lets > 0 then -- ./compiler/lua54.can:394 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 -toClose = toClose + (1) -- ./compiler/lua54.can:396 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 -if # lets > 0 then -- ./compiler/lua54.can:404 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 -toClose = toClose + (1) -- ./compiler/lua54.can:406 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -else -- ./compiler/lua54.can:408 -r = r .. ("else") -- ./compiler/lua54.can:411 -end -- ./compiler/lua54.can:411 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 -end -- ./compiler/lua54.can:413 -if # t % 2 == 1 then -- ./compiler/lua54.can:415 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 -end -- ./compiler/lua54.can:416 -r = r .. ("end") -- ./compiler/lua54.can:418 -for i = 1, toClose do -- ./compiler/lua54.can:419 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 -end -- ./compiler/lua54.can:420 -return r -- ./compiler/lua54.can:422 -end, -- ./compiler/lua54.can:422 -["Fornum"] = function(t) -- ./compiler/lua54.can:425 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 -if # t == 5 then -- ./compiler/lua54.can:427 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 -if hasContinue then -- ./compiler/lua54.can:430 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 -end -- ./compiler/lua54.can:431 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 -if hasContinue then -- ./compiler/lua54.can:434 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 -end -- ./compiler/lua54.can:435 -return r .. unindent() .. "end" -- ./compiler/lua54.can:437 -else -- ./compiler/lua54.can:437 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 -if hasContinue then -- ./compiler/lua54.can:441 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 -end -- ./compiler/lua54.can:442 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 -if hasContinue then -- ./compiler/lua54.can:445 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 -end -- ./compiler/lua54.can:446 -return r .. unindent() .. "end" -- ./compiler/lua54.can:448 -end -- ./compiler/lua54.can:448 -end, -- ./compiler/lua54.can:448 -["Forin"] = function(t) -- ./compiler/lua54.can:452 -local destructured = {} -- ./compiler/lua54.can:453 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 -if hasContinue then -- ./compiler/lua54.can:456 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 -end -- ./compiler/lua54.can:457 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 -if hasContinue then -- ./compiler/lua54.can:460 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 -end -- ./compiler/lua54.can:461 -return r .. unindent() .. "end" -- ./compiler/lua54.can:463 -end, -- ./compiler/lua54.can:463 -["Local"] = function(t) -- ./compiler/lua54.can:466 -local destructured = {} -- ./compiler/lua54.can:467 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 -if t[2][1] then -- ./compiler/lua54.can:469 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 -end -- ./compiler/lua54.can:470 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 -end, -- ./compiler/lua54.can:472 -["Let"] = function(t) -- ./compiler/lua54.can:475 -local destructured = {} -- ./compiler/lua54.can:476 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 -local r = "local " .. nameList -- ./compiler/lua54.can:478 -if t[2][1] then -- ./compiler/lua54.can:479 -if all(t[2], { -- ./compiler/lua54.can:480 -"Nil", -- ./compiler/lua54.can:480 -"Dots", -- ./compiler/lua54.can:480 -"Boolean", -- ./compiler/lua54.can:480 -"Number", -- ./compiler/lua54.can:480 -"String" -- ./compiler/lua54.can:480 -}) then -- ./compiler/lua54.can:480 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -else -- ./compiler/lua54.can:481 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Localrec"] = function(t) -- ./compiler/lua54.can:489 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Goto"] = function(t) -- ./compiler/lua54.can:493 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 -end, -- ./compiler/lua54.can:494 -["Label"] = function(t) -- ./compiler/lua54.can:497 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 -end, -- ./compiler/lua54.can:498 -["Return"] = function(t) -- ./compiler/lua54.can:501 -local push = peek("push") -- ./compiler/lua54.can:502 -if push then -- ./compiler/lua54.can:503 -local r = "" -- ./compiler/lua54.can:504 -for _, val in ipairs(t) do -- ./compiler/lua54.can:505 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 -end -- ./compiler/lua54.can:506 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 -else -- ./compiler/lua54.can:508 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -end, -- ./compiler/lua54.can:510 -["Push"] = function(t) -- ./compiler/lua54.can:514 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 -r = "" -- ./compiler/lua54.can:516 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 -end -- ./compiler/lua54.can:518 -if t[# t] then -- ./compiler/lua54.can:520 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 -else -- ./compiler/lua54.can:522 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -return r -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Break"] = function() -- ./compiler/lua54.can:530 -return "break" -- ./compiler/lua54.can:531 -end, -- ./compiler/lua54.can:531 -["Continue"] = function() -- ./compiler/lua54.can:534 -return "goto " .. var("continue") -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Nil"] = function() -- ./compiler/lua54.can:542 -return "nil" -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Dots"] = function() -- ./compiler/lua54.can:546 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 -return r -- ./compiler/lua54.can:552 -else -- ./compiler/lua54.can:552 -return "..." -- ./compiler/lua54.can:554 -end -- ./compiler/lua54.can:554 -end, -- ./compiler/lua54.can:554 -["Boolean"] = function(t) -- ./compiler/lua54.can:558 -return tostring(t[1]) -- ./compiler/lua54.can:559 -end, -- ./compiler/lua54.can:559 -["Number"] = function(t) -- ./compiler/lua54.can:562 -return tostring(t[1]) -- ./compiler/lua54.can:563 -end, -- ./compiler/lua54.can:563 -["String"] = function(t) -- ./compiler/lua54.can:566 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 -end, -- ./compiler/lua54.can:567 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 -local r = "(" -- ./compiler/lua54.can:571 -local decl = {} -- ./compiler/lua54.can:572 -if t[1][1] then -- ./compiler/lua54.can:573 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 -r = r .. (id) -- ./compiler/lua54.can:579 -else -- ./compiler/lua54.can:579 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 -r = r .. (", " .. id) -- ./compiler/lua54.can:589 -else -- ./compiler/lua54.can:589 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 -r = r .. (d .. newline()) -- ./compiler/lua54.can:597 -end -- ./compiler/lua54.can:597 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 -end -- ./compiler/lua54.can:600 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 -if hasPush then -- ./compiler/lua54.can:603 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 -else -- ./compiler/lua54.can:604 -push("push", false) -- ./compiler/lua54.can:606 -end -- ./compiler/lua54.can:606 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 -end -- ./compiler/lua54.can:610 -pop("push") -- ./compiler/lua54.can:612 -return r .. unindent() .. "end" -- ./compiler/lua54.can:613 -end, -- ./compiler/lua54.can:613 -["Function"] = function(t) -- ./compiler/lua54.can:615 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 -end, -- ./compiler/lua54.can:616 -["Pair"] = function(t) -- ./compiler/lua54.can:619 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 -end, -- ./compiler/lua54.can:620 -["Table"] = function(t) -- ./compiler/lua54.can:622 -if # t == 0 then -- ./compiler/lua54.can:623 -return "{}" -- ./compiler/lua54.can:624 -elseif # t == 1 then -- ./compiler/lua54.can:625 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 -end -- ./compiler/lua54.can:628 -end, -- ./compiler/lua54.can:628 -["TableCompr"] = function(t) -- ./compiler/lua54.can:632 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 -end, -- ./compiler/lua54.can:633 -["Op"] = function(t) -- ./compiler/lua54.can:636 -local r -- ./compiler/lua54.can:637 -if # t == 2 then -- ./compiler/lua54.can:638 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 -else -- ./compiler/lua54.can:640 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 -end -- ./compiler/lua54.can:642 -else -- ./compiler/lua54.can:642 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 -else -- ./compiler/lua54.can:646 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -return r -- ./compiler/lua54.can:651 -end, -- ./compiler/lua54.can:651 -["Paren"] = function(t) -- ./compiler/lua54.can:654 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 -end, -- ./compiler/lua54.can:655 -["MethodStub"] = function(t) -- ./compiler/lua54.can:658 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 -end, -- ./compiler/lua54.can:664 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 -end, -- ./compiler/lua54.can:674 -["LetExpr"] = function(t) -- ./compiler/lua54.can:681 -return lua(t[1][1]) -- ./compiler/lua54.can:682 -end, -- ./compiler/lua54.can:682 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 -local r = "(function()" .. indent() -- ./compiler/lua54.can:688 -if hasPush then -- ./compiler/lua54.can:689 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 -else -- ./compiler/lua54.can:690 -push("push", false) -- ./compiler/lua54.can:692 -end -- ./compiler/lua54.can:692 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 -if hasPush then -- ./compiler/lua54.can:695 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 -end -- ./compiler/lua54.can:696 -pop("push") -- ./compiler/lua54.can:698 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 -return r -- ./compiler/lua54.can:700 -end, -- ./compiler/lua54.can:700 -["DoExpr"] = function(t) -- ./compiler/lua54.can:703 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 -end -- ./compiler/lua54.can:705 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 -end, -- ./compiler/lua54.can:707 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 -end, -- ./compiler/lua54.can:711 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 -end, -- ./compiler/lua54.can:715 -["IfExpr"] = function(t) -- ./compiler/lua54.can:718 -for i = 2, # t do -- ./compiler/lua54.can:719 -local block = t[i] -- ./compiler/lua54.can:720 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 -end, -- ./compiler/lua54.can:725 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 -end, -- ./compiler/lua54.can:729 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["Call"] = function(t) -- ./compiler/lua54.can:739 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 -local replacement = macro["replacement"] -- ./compiler/lua54.can:744 -local r -- ./compiler/lua54.can:745 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 -if type(replacement) == "function" then -- ./compiler/lua54.can:747 -local args = {} -- ./compiler/lua54.can:748 -for i = 2, # t do -- ./compiler/lua54.can:749 -table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 -end -- ./compiler/lua54.can:750 -r = replacement(unpack(args)) -- ./compiler/lua54.can:752 -else -- ./compiler/lua54.can:752 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 -macroargs["..."] = (function() -- ./compiler/lua54.can:757 -local self = {} -- ./compiler/lua54.can:757 -for j = i + 1, # t do -- ./compiler/lua54.can:757 -self[#self+1] = t[j] -- ./compiler/lua54.can:757 -end -- ./compiler/lua54.can:757 -return self -- ./compiler/lua54.can:757 -end)() -- ./compiler/lua54.can:757 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 -if t[i + 1] == nil then -- ./compiler/lua54.can:759 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 -end -- ./compiler/lua54.can:760 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 -else -- ./compiler/lua54.can:762 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -push("macroargs", macroargs) -- ./compiler/lua54.can:767 -r = lua(replacement) -- ./compiler/lua54.can:768 -pop("macroargs") -- ./compiler/lua54.can:769 -end -- ./compiler/lua54.can:769 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 -return r -- ./compiler/lua54.can:772 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 -else -- ./compiler/lua54.can:775 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 -end -- ./compiler/lua54.can:777 -else -- ./compiler/lua54.can:777 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 -end -- ./compiler/lua54.can:780 -end, -- ./compiler/lua54.can:780 -["SafeCall"] = function(t) -- ./compiler/lua54.can:784 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 -else -- ./compiler/lua54.can:786 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 -end -- ./compiler/lua54.can:788 -end, -- ./compiler/lua54.can:788 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 -if start == nil then start = 1 end -- ./compiler/lua54.can:793 -local r -- ./compiler/lua54.can:794 -if t[start] then -- ./compiler/lua54.can:795 -r = lua(t[start]) -- ./compiler/lua54.can:796 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 -end -- ./compiler/lua54.can:798 -else -- ./compiler/lua54.can:798 -r = "" -- ./compiler/lua54.can:801 -end -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:803 -end, -- ./compiler/lua54.can:803 -["Id"] = function(t) -- ./compiler/lua54.can:806 -local r = t[1] -- ./compiler/lua54.can:807 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 -r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 -local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 -if type(macro) == "function" then -- ./compiler/lua54.can:815 -r = macro() -- ./compiler/lua54.can:816 -else -- ./compiler/lua54.can:816 -r = lua(macro) -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 -end -- ./compiler/lua54.can:821 -return r -- ./compiler/lua54.can:823 -end, -- ./compiler/lua54.can:823 -["AttributeId"] = function(t) -- ./compiler/lua54.can:826 -if t[2] then -- ./compiler/lua54.can:827 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 -else -- ./compiler/lua54.can:828 -return t[1] -- ./compiler/lua54.can:830 -end -- ./compiler/lua54.can:830 -end, -- ./compiler/lua54.can:830 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 -if t["id"] then -- ./compiler/lua54.can:835 -return t["id"] -- ./compiler/lua54.can:836 -else -- ./compiler/lua54.can:836 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 -for j = 1, # t, 1 do -- ./compiler/lua54.can:840 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 -end -- ./compiler/lua54.can:841 -table["insert"](d, vars) -- ./compiler/lua54.can:843 -t["id"] = vars["id"] -- ./compiler/lua54.can:844 -return vars["id"] -- ./compiler/lua54.can:845 -end -- ./compiler/lua54.can:845 -end, -- ./compiler/lua54.can:845 -["Index"] = function(t) -- ./compiler/lua54.can:849 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 -else -- ./compiler/lua54.can:851 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 -end -- ./compiler/lua54.can:853 -end, -- ./compiler/lua54.can:853 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 -local l = {} -- ./compiler/lua54.can:859 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 -table["insert"](l, 1, t) -- ./compiler/lua54.can:861 -t = t[1] -- ./compiler/lua54.can:862 -end -- ./compiler/lua54.can:862 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 -for _, e in ipairs(l) do -- ./compiler/lua54.can:865 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 -else -- ./compiler/lua54.can:868 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 -return r -- ./compiler/lua54.can:874 -else -- ./compiler/lua54.can:874 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 -end -- ./compiler/lua54.can:876 -end, -- ./compiler/lua54.can:876 -["_opid"] = { -- ./compiler/lua54.can:881 -["add"] = "+", -- ./compiler/lua54.can:882 -["sub"] = "-", -- ./compiler/lua54.can:882 -["mul"] = "*", -- ./compiler/lua54.can:882 -["div"] = "/", -- ./compiler/lua54.can:882 -["idiv"] = "//", -- ./compiler/lua54.can:883 -["mod"] = "%", -- ./compiler/lua54.can:883 -["pow"] = "^", -- ./compiler/lua54.can:883 -["concat"] = "..", -- ./compiler/lua54.can:883 -["band"] = "&", -- ./compiler/lua54.can:884 -["bor"] = "|", -- ./compiler/lua54.can:884 -["bxor"] = "~", -- ./compiler/lua54.can:884 -["shl"] = "<<", -- ./compiler/lua54.can:884 -["shr"] = ">>", -- ./compiler/lua54.can:884 -["eq"] = "==", -- ./compiler/lua54.can:885 -["ne"] = "~=", -- ./compiler/lua54.can:885 -["lt"] = "<", -- ./compiler/lua54.can:885 -["gt"] = ">", -- ./compiler/lua54.can:885 -["le"] = "<=", -- ./compiler/lua54.can:885 -["ge"] = ">=", -- ./compiler/lua54.can:885 -["and"] = "and", -- ./compiler/lua54.can:886 -["or"] = "or", -- ./compiler/lua54.can:886 -["unm"] = "-", -- ./compiler/lua54.can:886 -["len"] = "#", -- ./compiler/lua54.can:886 -["bnot"] = "~", -- ./compiler/lua54.can:886 -["not"] = "not" -- ./compiler/lua54.can:886 -} -- ./compiler/lua54.can:886 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 -end }) -- ./compiler/lua54.can:890 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 -return requireStr .. code -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -local lua54 = _() or lua54 -- ./compiler/lua54.can:902 -package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:903 -local function _() -- ./compiler/lua54.can:906 -local function _() -- ./compiler/lua54.can:908 -local util = require("candran.util") -- ./compiler/lua54.can:1 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 -return function(code, ast, options, macros) -- ./compiler/lua54.can:7 -if macros == nil then macros = { -- ./compiler/lua54.can:7 -["functions"] = {}, -- ./compiler/lua54.can:7 -["variables"] = {} -- ./compiler/lua54.can:7 -} end -- ./compiler/lua54.can:7 -local lastInputPos = 1 -- ./compiler/lua54.can:9 -local prevLinePos = 1 -- ./compiler/lua54.can:10 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 -local lastLine = 1 -- ./compiler/lua54.can:12 -local indentLevel = 0 -- ./compiler/lua54.can:15 -local function newline() -- ./compiler/lua54.can:17 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 -if options["mapLines"] then -- ./compiler/lua54.can:19 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +package["loaded"]["compiler.lua55"] = lua55 or true -- ./compiler/lua55.can:938 +local function _() -- ./compiler/lua55.can:941 +local function _() -- ./compiler/lua55.can:943 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:21 -if source and line then -- ./compiler/lua54.can:23 -lastSource = source -- ./compiler/lua54.can:24 -lastLine = tonumber(line) -- ./compiler/lua54.can:25 -else -- ./compiler/lua54.can:25 +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:27 -lastLine = lastLine + (1) -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -prevLinePos = lastInputPos -- ./compiler/lua54.can:32 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 -end -- ./compiler/lua54.can:34 -return r -- ./compiler/lua54.can:36 -end -- ./compiler/lua54.can:36 -local function indent() -- ./compiler/lua54.can:39 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 -return newline() -- ./compiler/lua54.can:41 +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +tags["Global"] = function(t) -- ./compiler/lua54.can:4 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:5 +end -- ./compiler/lua54.can:5 +tags["Globalrec"] = function(t) -- ./compiler/lua54.can:7 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:8 +end -- ./compiler/lua54.can:8 +tags["GlobalAll"] = function(t) -- ./compiler/lua54.can:10 +if # t == 1 then -- ./compiler/lua54.can:11 +error("target " .. targetName .. " does not support collective global variable declaration") -- ./compiler/lua54.can:12 +else -- ./compiler/lua54.can:12 +return "" -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +tags["_functionParameter"]["ParDots"] = function(t, decl) -- ./compiler/lua54.can:19 +if # t == 1 then -- ./compiler/lua54.can:20 +local id = lua(t[1]) -- ./compiler/lua54.can:21 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:22 +table["insert"](decl, "local " .. id .. " = { ... }") -- ./compiler/lua54.can:23 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +return "..." -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua54.can:31 +local ids = {} -- ./compiler/lua54.can:32 +for i = 2, # t, 1 do -- ./compiler/lua54.can:33 +if t[i][2] then -- ./compiler/lua54.can:34 +error("target " .. targetName .. " does not support combining prefixed and suffixed attributes in variable declaration") -- ./compiler/lua54.can:35 +else -- ./compiler/lua54.can:35 +t[i][2] = t[1] -- ./compiler/lua54.can:37 +table["insert"](ids, lua(t[i])) -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +return table["concat"](ids, ", ") -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +return lua55 -- ./compiler/lua54.can:50 +end -- ./compiler/lua54.can:50 +local lua54 = _() or lua54 -- ./compiler/lua54.can:54 +package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:55 +local function _() -- ./compiler/lua54.can:58 +local function _() -- ./compiler/lua54.can:60 +local function _() -- ./compiler/lua54.can:62 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 +local source, line = sub:sub(1, sub:find("\ +")):match(".*%-%- (.-)%:(%d+)\ +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 +for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +tags["Global"] = function(t) -- ./compiler/lua54.can:4 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:5 +end -- ./compiler/lua54.can:5 +tags["Globalrec"] = function(t) -- ./compiler/lua54.can:7 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:8 +end -- ./compiler/lua54.can:8 +tags["GlobalAll"] = function(t) -- ./compiler/lua54.can:10 +if # t == 1 then -- ./compiler/lua54.can:11 +error("target " .. targetName .. " does not support collective global variable declaration") -- ./compiler/lua54.can:12 +else -- ./compiler/lua54.can:12 +return "" -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +tags["_functionParameter"]["ParDots"] = function(t, decl) -- ./compiler/lua54.can:19 +if # t == 1 then -- ./compiler/lua54.can:20 +local id = lua(t[1]) -- ./compiler/lua54.can:21 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:22 +table["insert"](decl, "local " .. id .. " = { ... }") -- ./compiler/lua54.can:23 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +return "..." -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua54.can:31 +local ids = {} -- ./compiler/lua54.can:32 +for i = 2, # t, 1 do -- ./compiler/lua54.can:33 +if t[i][2] then -- ./compiler/lua54.can:34 +error("target " .. targetName .. " does not support combining prefixed and suffixed attributes in variable declaration") -- ./compiler/lua54.can:35 +else -- ./compiler/lua54.can:35 +t[i][2] = t[1] -- ./compiler/lua54.can:37 +table["insert"](ids, lua(t[i])) -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +return table["concat"](ids, ", ") -- ./compiler/lua54.can:41 end -- ./compiler/lua54.can:41 -local function unindent() -- ./compiler/lua54.can:44 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 -return newline() -- ./compiler/lua54.can:46 -end -- ./compiler/lua54.can:46 -local states = { -- ./compiler/lua54.can:51 -["push"] = {}, -- ./compiler/lua54.can:52 -["destructuring"] = {}, -- ./compiler/lua54.can:53 -["scope"] = {}, -- ./compiler/lua54.can:54 -["macroargs"] = {} -- ./compiler/lua54.can:55 -} -- ./compiler/lua54.can:55 -local function push(name, state) -- ./compiler/lua54.can:58 -table["insert"](states[name], state) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function pop(name) -- ./compiler/lua54.can:63 -table["remove"](states[name]) -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function set(name, state) -- ./compiler/lua54.can:68 -states[name][# states[name]] = state -- ./compiler/lua54.can:69 -return "" -- ./compiler/lua54.can:70 -end -- ./compiler/lua54.can:70 -local function peek(name) -- ./compiler/lua54.can:73 -return states[name][# states[name]] -- ./compiler/lua54.can:74 -end -- ./compiler/lua54.can:74 -local function var(name) -- ./compiler/lua54.can:79 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 -end -- ./compiler/lua54.can:80 -local function tmp() -- ./compiler/lua54.can:84 -local scope = peek("scope") -- ./compiler/lua54.can:85 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 -table["insert"](scope, var) -- ./compiler/lua54.can:87 -return var -- ./compiler/lua54.can:88 -end -- ./compiler/lua54.can:88 -local nomacro = { -- ./compiler/lua54.can:92 -["variables"] = {}, -- ./compiler/lua54.can:92 -["functions"] = {} -- ./compiler/lua54.can:92 -} -- ./compiler/lua54.can:92 -local required = {} -- ./compiler/lua54.can:95 -local requireStr = "" -- ./compiler/lua54.can:96 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 -if not required[req] then -- ./compiler/lua54.can:100 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 -required[req] = true -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -local loop = { -- ./compiler/lua54.can:107 -"While", -- ./compiler/lua54.can:107 -"Repeat", -- ./compiler/lua54.can:107 -"Fornum", -- ./compiler/lua54.can:107 -"Forin", -- ./compiler/lua54.can:107 -"WhileExpr", -- ./compiler/lua54.can:107 -"RepeatExpr", -- ./compiler/lua54.can:107 -"FornumExpr", -- ./compiler/lua54.can:107 -"ForinExpr" -- ./compiler/lua54.can:107 -} -- ./compiler/lua54.can:107 -local func = { -- ./compiler/lua54.can:108 -"Function", -- ./compiler/lua54.can:108 -"TableCompr", -- ./compiler/lua54.can:108 -"DoExpr", -- ./compiler/lua54.can:108 -"WhileExpr", -- ./compiler/lua54.can:108 -"RepeatExpr", -- ./compiler/lua54.can:108 -"IfExpr", -- ./compiler/lua54.can:108 -"FornumExpr", -- ./compiler/lua54.can:108 -"ForinExpr" -- ./compiler/lua54.can:108 -} -- ./compiler/lua54.can:108 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 -local tagsCheck = {} -- ./compiler/lua54.can:113 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 -tagsCheck[tag] = true -- ./compiler/lua54.can:115 -end -- ./compiler/lua54.can:115 -local nofollowCheck = {} -- ./compiler/lua54.can:117 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 -nofollowCheck[tag] = true -- ./compiler/lua54.can:119 -end -- ./compiler/lua54.can:119 -for _, node in ipairs(list) do -- ./compiler/lua54.can:121 -if type(node) == "table" then -- ./compiler/lua54.can:122 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 -return node -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 -if r then -- ./compiler/lua54.can:128 -return r -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -return nil -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 -local tagsCheck = {} -- ./compiler/lua54.can:138 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 -tagsCheck[tag] = true -- ./compiler/lua54.can:140 -end -- ./compiler/lua54.can:140 -local nofollowCheck = {} -- ./compiler/lua54.can:142 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 -nofollowCheck[tag] = true -- ./compiler/lua54.can:144 -end -- ./compiler/lua54.can:144 -local found = {} -- ./compiler/lua54.can:146 -for _, node in ipairs(list) do -- ./compiler/lua54.can:147 -if type(node) == "table" then -- ./compiler/lua54.can:148 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 -table["insert"](found, n) -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 -table["insert"](found, node) -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -return found -- ./compiler/lua54.can:159 -end -- ./compiler/lua54.can:159 -local function all(list, tags) -- ./compiler/lua54.can:163 -for _, node in ipairs(list) do -- ./compiler/lua54.can:164 -local ok = false -- ./compiler/lua54.can:165 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 -if node["tag"] == tag then -- ./compiler/lua54.can:167 -ok = true -- ./compiler/lua54.can:168 -break -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -if not ok then -- ./compiler/lua54.can:172 -return false -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -return true -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -local tags -- ./compiler/lua54.can:180 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 -end -- ./compiler/lua54.can:184 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 -end -- ./compiler/lua54.can:191 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 -end -- ./compiler/lua54.can:194 -local CONTINUE_START = function() -- ./compiler/lua54.can:196 -return "do" .. indent() -- ./compiler/lua54.can:197 -end -- ./compiler/lua54.can:197 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 -end -- ./compiler/lua54.can:200 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 -local vars = {} -- ./compiler/lua54.can:203 -local values = {} -- ./compiler/lua54.can:204 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 -for _, v in ipairs(list) do -- ./compiler/lua54.can:206 -local var, val -- ./compiler/lua54.can:207 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 -var = v -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Index", -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Id", -- ./compiler/lua54.can:210 -list["id"] -- ./compiler/lua54.can:210 -}, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "String", -- ./compiler/lua54.can:210 -v[1] -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 -var = v[2] -- ./compiler/lua54.can:212 -val = { -- ./compiler/lua54.can:213 -["tag"] = "Index", -- ./compiler/lua54.can:213 -{ -- ./compiler/lua54.can:213 -["tag"] = "Id", -- ./compiler/lua54.can:213 -list["id"] -- ./compiler/lua54.can:213 -}, -- ./compiler/lua54.can:213 -v[1] -- ./compiler/lua54.can:213 -} -- ./compiler/lua54.can:213 -else -- ./compiler/lua54.can:213 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 -end -- ./compiler/lua54.can:215 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 -val = { -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["rightOp"], -- ./compiler/lua54.can:218 -var, -- ./compiler/lua54.can:218 -{ -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["leftOp"], -- ./compiler/lua54.can:218 -val, -- ./compiler/lua54.can:218 -var -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 -val = { -- ./compiler/lua54.can:220 -["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["rightOp"], -- ./compiler/lua54.can:220 -var, -- ./compiler/lua54.can:220 -val -- ./compiler/lua54.can:220 -} -- ./compiler/lua54.can:220 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 -val = { -- ./compiler/lua54.can:222 -["tag"] = "Op", -- ./compiler/lua54.can:222 -destructured["leftOp"], -- ./compiler/lua54.can:222 -val, -- ./compiler/lua54.can:222 -var -- ./compiler/lua54.can:222 -} -- ./compiler/lua54.can:222 -end -- ./compiler/lua54.can:222 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -if # vars > 0 then -- ./compiler/lua54.can:228 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 -if newlineAfter then -- ./compiler/lua54.can:230 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 -else -- ./compiler/lua54.can:231 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 -end -- ./compiler/lua54.can:233 -else -- ./compiler/lua54.can:233 -return "" -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -tags = setmetatable({ -- ./compiler/lua54.can:241 -["Block"] = function(t) -- ./compiler/lua54.can:243 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 -hasPush = false -- ./compiler/lua54.can:247 -end -- ./compiler/lua54.can:247 -local r = push("scope", {}) -- ./compiler/lua54.can:249 -if hasPush then -- ./compiler/lua54.can:250 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 -end -- ./compiler/lua54.can:251 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 -end -- ./compiler/lua54.can:254 -if t[# t] then -- ./compiler/lua54.can:256 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 -end -- ./compiler/lua54.can:257 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 -end -- ./compiler/lua54.can:260 -return r .. pop("scope") -- ./compiler/lua54.can:262 -end, -- ./compiler/lua54.can:262 -["Do"] = function(t) -- ./compiler/lua54.can:268 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 -end, -- ./compiler/lua54.can:269 -["Set"] = function(t) -- ./compiler/lua54.can:272 -local expr = t[# t] -- ./compiler/lua54.can:274 -local vars, values = {}, {} -- ./compiler/lua54.can:275 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 -else -- ./compiler/lua54.can:280 -table["insert"](vars, n) -- ./compiler/lua54.can:282 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 -local r = "" -- ./compiler/lua54.can:288 -if # vars > 0 then -- ./compiler/lua54.can:289 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 -end -- ./compiler/lua54.can:290 -if # destructuringVars > 0 then -- ./compiler/lua54.can:292 -local destructured = {} -- ./compiler/lua54.can:293 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 -end -- ./compiler/lua54.can:295 -return r -- ./compiler/lua54.can:297 -elseif # t == 4 then -- ./compiler/lua54.can:298 -if t[3] == "=" then -- ./compiler/lua54.can:299 -local r = "" -- ./compiler/lua54.can:300 -if # vars > 0 then -- ./compiler/lua54.can:301 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 -t[2], -- ./compiler/lua54.can:302 -vars[1], -- ./compiler/lua54.can:302 -{ -- ./compiler/lua54.can:302 -["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[1] -- ./compiler/lua54.can:302 -} -- ./compiler/lua54.can:302 -}, "Op")) -- ./compiler/lua54.can:302 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 -t[2], -- ./compiler/lua54.can:304 -vars[i], -- ./compiler/lua54.can:304 -{ -- ./compiler/lua54.can:304 -["tag"] = "Paren", -- ./compiler/lua54.can:304 -values[i] -- ./compiler/lua54.can:304 -} -- ./compiler/lua54.can:304 -}, "Op")) -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -if # destructuringVars > 0 then -- ./compiler/lua54.can:307 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -return r -- ./compiler/lua54.can:312 -else -- ./compiler/lua54.can:312 -local r = "" -- ./compiler/lua54.can:314 -if # vars > 0 then -- ./compiler/lua54.can:315 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 -t[3], -- ./compiler/lua54.can:316 -{ -- ./compiler/lua54.can:316 -["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[1] -- ./compiler/lua54.can:316 -}, -- ./compiler/lua54.can:316 -vars[1] -- ./compiler/lua54.can:316 -}, "Op")) -- ./compiler/lua54.can:316 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 -t[3], -- ./compiler/lua54.can:318 -{ -- ./compiler/lua54.can:318 -["tag"] = "Paren", -- ./compiler/lua54.can:318 -values[i] -- ./compiler/lua54.can:318 -}, -- ./compiler/lua54.can:318 -vars[i] -- ./compiler/lua54.can:318 -}, "Op")) -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -if # destructuringVars > 0 then -- ./compiler/lua54.can:321 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 -end -- ./compiler/lua54.can:324 -return r -- ./compiler/lua54.can:326 -end -- ./compiler/lua54.can:326 -else -- ./compiler/lua54.can:326 -local r = "" -- ./compiler/lua54.can:329 -if # vars > 0 then -- ./compiler/lua54.can:330 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 -t[2], -- ./compiler/lua54.can:331 -vars[1], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Op", -- ./compiler/lua54.can:331 -t[4], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[1] -- ./compiler/lua54.can:331 -}, -- ./compiler/lua54.can:331 -vars[1] -- ./compiler/lua54.can:331 -} -- ./compiler/lua54.can:331 -}, "Op")) -- ./compiler/lua54.can:331 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 -t[2], -- ./compiler/lua54.can:333 -vars[i], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Op", -- ./compiler/lua54.can:333 -t[4], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Paren", -- ./compiler/lua54.can:333 -values[i] -- ./compiler/lua54.can:333 -}, -- ./compiler/lua54.can:333 -vars[i] -- ./compiler/lua54.can:333 -} -- ./compiler/lua54.can:333 -}, "Op")) -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -if # destructuringVars > 0 then -- ./compiler/lua54.can:336 -local destructured = { -- ./compiler/lua54.can:337 -["rightOp"] = t[2], -- ./compiler/lua54.can:337 -["leftOp"] = t[4] -- ./compiler/lua54.can:337 -} -- ./compiler/lua54.can:337 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 -end -- ./compiler/lua54.can:339 -return r -- ./compiler/lua54.can:341 -end -- ./compiler/lua54.can:341 -end, -- ./compiler/lua54.can:341 -["While"] = function(t) -- ./compiler/lua54.can:345 -local r = "" -- ./compiler/lua54.can:346 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 -if # lets > 0 then -- ./compiler/lua54.can:349 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 -if # lets > 0 then -- ./compiler/lua54.can:356 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 -end -- ./compiler/lua54.can:357 -if hasContinue then -- ./compiler/lua54.can:359 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 -end -- ./compiler/lua54.can:360 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 -if hasContinue then -- ./compiler/lua54.can:363 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 -end -- ./compiler/lua54.can:364 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 -if # lets > 0 then -- ./compiler/lua54.can:367 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 -end -- ./compiler/lua54.can:369 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 -end -- ./compiler/lua54.can:371 -return r -- ./compiler/lua54.can:373 -end, -- ./compiler/lua54.can:373 -["Repeat"] = function(t) -- ./compiler/lua54.can:376 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 -local r = "repeat" .. indent() -- ./compiler/lua54.can:378 -if hasContinue then -- ./compiler/lua54.can:379 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 -end -- ./compiler/lua54.can:380 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 -if hasContinue then -- ./compiler/lua54.can:383 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 -end -- ./compiler/lua54.can:384 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 -return r -- ./compiler/lua54.can:387 -end, -- ./compiler/lua54.can:387 -["If"] = function(t) -- ./compiler/lua54.can:390 -local r = "" -- ./compiler/lua54.can:391 -local toClose = 0 -- ./compiler/lua54.can:392 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 -if # lets > 0 then -- ./compiler/lua54.can:394 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 -toClose = toClose + (1) -- ./compiler/lua54.can:396 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 -if # lets > 0 then -- ./compiler/lua54.can:404 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 -toClose = toClose + (1) -- ./compiler/lua54.can:406 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -else -- ./compiler/lua54.can:408 -r = r .. ("else") -- ./compiler/lua54.can:411 -end -- ./compiler/lua54.can:411 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 -end -- ./compiler/lua54.can:413 -if # t % 2 == 1 then -- ./compiler/lua54.can:415 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 -end -- ./compiler/lua54.can:416 -r = r .. ("end") -- ./compiler/lua54.can:418 -for i = 1, toClose do -- ./compiler/lua54.can:419 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 -end -- ./compiler/lua54.can:420 -return r -- ./compiler/lua54.can:422 -end, -- ./compiler/lua54.can:422 -["Fornum"] = function(t) -- ./compiler/lua54.can:425 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 -if # t == 5 then -- ./compiler/lua54.can:427 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 -if hasContinue then -- ./compiler/lua54.can:430 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 -end -- ./compiler/lua54.can:431 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 -if hasContinue then -- ./compiler/lua54.can:434 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 -end -- ./compiler/lua54.can:435 -return r .. unindent() .. "end" -- ./compiler/lua54.can:437 -else -- ./compiler/lua54.can:437 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 -if hasContinue then -- ./compiler/lua54.can:441 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 -end -- ./compiler/lua54.can:442 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 -if hasContinue then -- ./compiler/lua54.can:445 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 -end -- ./compiler/lua54.can:446 -return r .. unindent() .. "end" -- ./compiler/lua54.can:448 -end -- ./compiler/lua54.can:448 -end, -- ./compiler/lua54.can:448 -["Forin"] = function(t) -- ./compiler/lua54.can:452 -local destructured = {} -- ./compiler/lua54.can:453 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 -if hasContinue then -- ./compiler/lua54.can:456 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 -end -- ./compiler/lua54.can:457 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 -if hasContinue then -- ./compiler/lua54.can:460 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 -end -- ./compiler/lua54.can:461 -return r .. unindent() .. "end" -- ./compiler/lua54.can:463 -end, -- ./compiler/lua54.can:463 -["Local"] = function(t) -- ./compiler/lua54.can:466 -local destructured = {} -- ./compiler/lua54.can:467 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 -if t[2][1] then -- ./compiler/lua54.can:469 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 -end -- ./compiler/lua54.can:470 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 -end, -- ./compiler/lua54.can:472 -["Let"] = function(t) -- ./compiler/lua54.can:475 -local destructured = {} -- ./compiler/lua54.can:476 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 -local r = "local " .. nameList -- ./compiler/lua54.can:478 -if t[2][1] then -- ./compiler/lua54.can:479 -if all(t[2], { -- ./compiler/lua54.can:480 -"Nil", -- ./compiler/lua54.can:480 -"Dots", -- ./compiler/lua54.can:480 -"Boolean", -- ./compiler/lua54.can:480 -"Number", -- ./compiler/lua54.can:480 -"String" -- ./compiler/lua54.can:480 -}) then -- ./compiler/lua54.can:480 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -else -- ./compiler/lua54.can:481 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Localrec"] = function(t) -- ./compiler/lua54.can:489 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Goto"] = function(t) -- ./compiler/lua54.can:493 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 -end, -- ./compiler/lua54.can:494 -["Label"] = function(t) -- ./compiler/lua54.can:497 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 -end, -- ./compiler/lua54.can:498 -["Return"] = function(t) -- ./compiler/lua54.can:501 -local push = peek("push") -- ./compiler/lua54.can:502 -if push then -- ./compiler/lua54.can:503 -local r = "" -- ./compiler/lua54.can:504 -for _, val in ipairs(t) do -- ./compiler/lua54.can:505 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 -end -- ./compiler/lua54.can:506 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 -else -- ./compiler/lua54.can:508 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -end, -- ./compiler/lua54.can:510 -["Push"] = function(t) -- ./compiler/lua54.can:514 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 -r = "" -- ./compiler/lua54.can:516 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 -end -- ./compiler/lua54.can:518 -if t[# t] then -- ./compiler/lua54.can:520 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 -else -- ./compiler/lua54.can:522 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -return r -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Break"] = function() -- ./compiler/lua54.can:530 -return "break" -- ./compiler/lua54.can:531 -end, -- ./compiler/lua54.can:531 -["Continue"] = function() -- ./compiler/lua54.can:534 -return "goto " .. var("continue") -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Nil"] = function() -- ./compiler/lua54.can:542 -return "nil" -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Dots"] = function() -- ./compiler/lua54.can:546 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 -return r -- ./compiler/lua54.can:552 -else -- ./compiler/lua54.can:552 -return "..." -- ./compiler/lua54.can:554 -end -- ./compiler/lua54.can:554 -end, -- ./compiler/lua54.can:554 -["Boolean"] = function(t) -- ./compiler/lua54.can:558 -return tostring(t[1]) -- ./compiler/lua54.can:559 -end, -- ./compiler/lua54.can:559 -["Number"] = function(t) -- ./compiler/lua54.can:562 -return tostring(t[1]) -- ./compiler/lua54.can:563 -end, -- ./compiler/lua54.can:563 -["String"] = function(t) -- ./compiler/lua54.can:566 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 -end, -- ./compiler/lua54.can:567 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 -local r = "(" -- ./compiler/lua54.can:571 -local decl = {} -- ./compiler/lua54.can:572 -if t[1][1] then -- ./compiler/lua54.can:573 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 -r = r .. (id) -- ./compiler/lua54.can:579 -else -- ./compiler/lua54.can:579 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 -r = r .. (", " .. id) -- ./compiler/lua54.can:589 -else -- ./compiler/lua54.can:589 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 -r = r .. (d .. newline()) -- ./compiler/lua54.can:597 -end -- ./compiler/lua54.can:597 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 -end -- ./compiler/lua54.can:600 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 -if hasPush then -- ./compiler/lua54.can:603 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 -else -- ./compiler/lua54.can:604 -push("push", false) -- ./compiler/lua54.can:606 -end -- ./compiler/lua54.can:606 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 -end -- ./compiler/lua54.can:610 -pop("push") -- ./compiler/lua54.can:612 -return r .. unindent() .. "end" -- ./compiler/lua54.can:613 -end, -- ./compiler/lua54.can:613 -["Function"] = function(t) -- ./compiler/lua54.can:615 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 -end, -- ./compiler/lua54.can:616 -["Pair"] = function(t) -- ./compiler/lua54.can:619 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 -end, -- ./compiler/lua54.can:620 -["Table"] = function(t) -- ./compiler/lua54.can:622 -if # t == 0 then -- ./compiler/lua54.can:623 -return "{}" -- ./compiler/lua54.can:624 -elseif # t == 1 then -- ./compiler/lua54.can:625 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 -end -- ./compiler/lua54.can:628 -end, -- ./compiler/lua54.can:628 -["TableCompr"] = function(t) -- ./compiler/lua54.can:632 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 -end, -- ./compiler/lua54.can:633 -["Op"] = function(t) -- ./compiler/lua54.can:636 -local r -- ./compiler/lua54.can:637 -if # t == 2 then -- ./compiler/lua54.can:638 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 -else -- ./compiler/lua54.can:640 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 -end -- ./compiler/lua54.can:642 -else -- ./compiler/lua54.can:642 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 -else -- ./compiler/lua54.can:646 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -return r -- ./compiler/lua54.can:651 -end, -- ./compiler/lua54.can:651 -["Paren"] = function(t) -- ./compiler/lua54.can:654 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 -end, -- ./compiler/lua54.can:655 -["MethodStub"] = function(t) -- ./compiler/lua54.can:658 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 -end, -- ./compiler/lua54.can:664 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 -end, -- ./compiler/lua54.can:674 -["LetExpr"] = function(t) -- ./compiler/lua54.can:681 -return lua(t[1][1]) -- ./compiler/lua54.can:682 -end, -- ./compiler/lua54.can:682 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 -local r = "(function()" .. indent() -- ./compiler/lua54.can:688 -if hasPush then -- ./compiler/lua54.can:689 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 -else -- ./compiler/lua54.can:690 -push("push", false) -- ./compiler/lua54.can:692 -end -- ./compiler/lua54.can:692 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 -if hasPush then -- ./compiler/lua54.can:695 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 -end -- ./compiler/lua54.can:696 -pop("push") -- ./compiler/lua54.can:698 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 -return r -- ./compiler/lua54.can:700 -end, -- ./compiler/lua54.can:700 -["DoExpr"] = function(t) -- ./compiler/lua54.can:703 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 -end -- ./compiler/lua54.can:705 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 -end, -- ./compiler/lua54.can:707 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 -end, -- ./compiler/lua54.can:711 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 -end, -- ./compiler/lua54.can:715 -["IfExpr"] = function(t) -- ./compiler/lua54.can:718 -for i = 2, # t do -- ./compiler/lua54.can:719 -local block = t[i] -- ./compiler/lua54.can:720 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 -end, -- ./compiler/lua54.can:725 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 -end, -- ./compiler/lua54.can:729 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["Call"] = function(t) -- ./compiler/lua54.can:739 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 -local replacement = macro["replacement"] -- ./compiler/lua54.can:744 -local r -- ./compiler/lua54.can:745 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 -if type(replacement) == "function" then -- ./compiler/lua54.can:747 -local args = {} -- ./compiler/lua54.can:748 -for i = 2, # t do -- ./compiler/lua54.can:749 -table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 -end -- ./compiler/lua54.can:750 -r = replacement(unpack(args)) -- ./compiler/lua54.can:752 -else -- ./compiler/lua54.can:752 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 -macroargs["..."] = (function() -- ./compiler/lua54.can:757 -local self = {} -- ./compiler/lua54.can:757 -for j = i + 1, # t do -- ./compiler/lua54.can:757 -self[#self+1] = t[j] -- ./compiler/lua54.can:757 -end -- ./compiler/lua54.can:757 -return self -- ./compiler/lua54.can:757 -end)() -- ./compiler/lua54.can:757 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 -if t[i + 1] == nil then -- ./compiler/lua54.can:759 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 -end -- ./compiler/lua54.can:760 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 -else -- ./compiler/lua54.can:762 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -push("macroargs", macroargs) -- ./compiler/lua54.can:767 -r = lua(replacement) -- ./compiler/lua54.can:768 -pop("macroargs") -- ./compiler/lua54.can:769 -end -- ./compiler/lua54.can:769 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 -return r -- ./compiler/lua54.can:772 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 -else -- ./compiler/lua54.can:775 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 -end -- ./compiler/lua54.can:777 -else -- ./compiler/lua54.can:777 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 -end -- ./compiler/lua54.can:780 -end, -- ./compiler/lua54.can:780 -["SafeCall"] = function(t) -- ./compiler/lua54.can:784 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 -else -- ./compiler/lua54.can:786 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 -end -- ./compiler/lua54.can:788 -end, -- ./compiler/lua54.can:788 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 -if start == nil then start = 1 end -- ./compiler/lua54.can:793 -local r -- ./compiler/lua54.can:794 -if t[start] then -- ./compiler/lua54.can:795 -r = lua(t[start]) -- ./compiler/lua54.can:796 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 -end -- ./compiler/lua54.can:798 -else -- ./compiler/lua54.can:798 -r = "" -- ./compiler/lua54.can:801 -end -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:803 -end, -- ./compiler/lua54.can:803 -["Id"] = function(t) -- ./compiler/lua54.can:806 -local r = t[1] -- ./compiler/lua54.can:807 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 -r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 -local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 -if type(macro) == "function" then -- ./compiler/lua54.can:815 -r = macro() -- ./compiler/lua54.can:816 -else -- ./compiler/lua54.can:816 -r = lua(macro) -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 -end -- ./compiler/lua54.can:821 -return r -- ./compiler/lua54.can:823 -end, -- ./compiler/lua54.can:823 -["AttributeId"] = function(t) -- ./compiler/lua54.can:826 -if t[2] then -- ./compiler/lua54.can:827 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 -else -- ./compiler/lua54.can:828 -return t[1] -- ./compiler/lua54.can:830 -end -- ./compiler/lua54.can:830 -end, -- ./compiler/lua54.can:830 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 -if t["id"] then -- ./compiler/lua54.can:835 -return t["id"] -- ./compiler/lua54.can:836 -else -- ./compiler/lua54.can:836 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 -for j = 1, # t, 1 do -- ./compiler/lua54.can:840 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 -end -- ./compiler/lua54.can:841 -table["insert"](d, vars) -- ./compiler/lua54.can:843 -t["id"] = vars["id"] -- ./compiler/lua54.can:844 -return vars["id"] -- ./compiler/lua54.can:845 -end -- ./compiler/lua54.can:845 -end, -- ./compiler/lua54.can:845 -["Index"] = function(t) -- ./compiler/lua54.can:849 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 -else -- ./compiler/lua54.can:851 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 -end -- ./compiler/lua54.can:853 -end, -- ./compiler/lua54.can:853 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 -local l = {} -- ./compiler/lua54.can:859 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 -table["insert"](l, 1, t) -- ./compiler/lua54.can:861 -t = t[1] -- ./compiler/lua54.can:862 -end -- ./compiler/lua54.can:862 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 -for _, e in ipairs(l) do -- ./compiler/lua54.can:865 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 -else -- ./compiler/lua54.can:868 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 -return r -- ./compiler/lua54.can:874 -else -- ./compiler/lua54.can:874 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 -end -- ./compiler/lua54.can:876 -end, -- ./compiler/lua54.can:876 -["_opid"] = { -- ./compiler/lua54.can:881 -["add"] = "+", -- ./compiler/lua54.can:882 -["sub"] = "-", -- ./compiler/lua54.can:882 -["mul"] = "*", -- ./compiler/lua54.can:882 -["div"] = "/", -- ./compiler/lua54.can:882 -["idiv"] = "//", -- ./compiler/lua54.can:883 -["mod"] = "%", -- ./compiler/lua54.can:883 -["pow"] = "^", -- ./compiler/lua54.can:883 -["concat"] = "..", -- ./compiler/lua54.can:883 -["band"] = "&", -- ./compiler/lua54.can:884 -["bor"] = "|", -- ./compiler/lua54.can:884 -["bxor"] = "~", -- ./compiler/lua54.can:884 -["shl"] = "<<", -- ./compiler/lua54.can:884 -["shr"] = ">>", -- ./compiler/lua54.can:884 -["eq"] = "==", -- ./compiler/lua54.can:885 -["ne"] = "~=", -- ./compiler/lua54.can:885 -["lt"] = "<", -- ./compiler/lua54.can:885 -["gt"] = ">", -- ./compiler/lua54.can:885 -["le"] = "<=", -- ./compiler/lua54.can:885 -["ge"] = ">=", -- ./compiler/lua54.can:885 -["and"] = "and", -- ./compiler/lua54.can:886 -["or"] = "or", -- ./compiler/lua54.can:886 -["unm"] = "-", -- ./compiler/lua54.can:886 -["len"] = "#", -- ./compiler/lua54.can:886 -["bnot"] = "~", -- ./compiler/lua54.can:886 -["not"] = "not" -- ./compiler/lua54.can:886 -} -- ./compiler/lua54.can:886 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 -end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -2228,945 +3324,1016 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 -return requireStr .. code -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -local lua54 = _() or lua54 -- ./compiler/lua54.can:902 -return lua54 -- ./compiler/lua53.can:18 -end -- ./compiler/lua53.can:18 -local lua53 = _() or lua53 -- ./compiler/lua53.can:22 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:23 -local function _() -- ./compiler/lua53.can:26 -local function _() -- ./compiler/lua53.can:28 -local function _() -- ./compiler/lua53.can:30 -local util = require("candran.util") -- ./compiler/lua54.can:1 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 -return function(code, ast, options, macros) -- ./compiler/lua54.can:7 -if macros == nil then macros = { -- ./compiler/lua54.can:7 -["functions"] = {}, -- ./compiler/lua54.can:7 -["variables"] = {} -- ./compiler/lua54.can:7 -} end -- ./compiler/lua54.can:7 -local lastInputPos = 1 -- ./compiler/lua54.can:9 -local prevLinePos = 1 -- ./compiler/lua54.can:10 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 -local lastLine = 1 -- ./compiler/lua54.can:12 -local indentLevel = 0 -- ./compiler/lua54.can:15 -local function newline() -- ./compiler/lua54.can:17 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 -if options["mapLines"] then -- ./compiler/lua54.can:19 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua53.can:11 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:12 +end -- ./compiler/lua53.can:12 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +return lua55 -- ./compiler/lua54.can:50 +end -- ./compiler/lua54.can:50 +local lua54 = _() or lua54 -- ./compiler/lua54.can:54 +return lua54 -- ./compiler/lua53.can:21 +end -- ./compiler/lua53.can:21 +local lua53 = _() or lua53 -- ./compiler/lua53.can:25 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:26 +local function _() -- ./compiler/lua53.can:29 +local function _() -- ./compiler/lua53.can:31 +local function _() -- ./compiler/lua53.can:33 +local function _() -- ./compiler/lua53.can:35 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:21 -if source and line then -- ./compiler/lua54.can:23 -lastSource = source -- ./compiler/lua54.can:24 -lastLine = tonumber(line) -- ./compiler/lua54.can:25 -else -- ./compiler/lua54.can:25 +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:27 -lastLine = lastLine + (1) -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -prevLinePos = lastInputPos -- ./compiler/lua54.can:32 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 -end -- ./compiler/lua54.can:34 -return r -- ./compiler/lua54.can:36 -end -- ./compiler/lua54.can:36 -local function indent() -- ./compiler/lua54.can:39 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 -return newline() -- ./compiler/lua54.can:41 +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +tags["Global"] = function(t) -- ./compiler/lua54.can:4 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:5 +end -- ./compiler/lua54.can:5 +tags["Globalrec"] = function(t) -- ./compiler/lua54.can:7 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:8 +end -- ./compiler/lua54.can:8 +tags["GlobalAll"] = function(t) -- ./compiler/lua54.can:10 +if # t == 1 then -- ./compiler/lua54.can:11 +error("target " .. targetName .. " does not support collective global variable declaration") -- ./compiler/lua54.can:12 +else -- ./compiler/lua54.can:12 +return "" -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +tags["_functionParameter"]["ParDots"] = function(t, decl) -- ./compiler/lua54.can:19 +if # t == 1 then -- ./compiler/lua54.can:20 +local id = lua(t[1]) -- ./compiler/lua54.can:21 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:22 +table["insert"](decl, "local " .. id .. " = { ... }") -- ./compiler/lua54.can:23 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +return "..." -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua54.can:31 +local ids = {} -- ./compiler/lua54.can:32 +for i = 2, # t, 1 do -- ./compiler/lua54.can:33 +if t[i][2] then -- ./compiler/lua54.can:34 +error("target " .. targetName .. " does not support combining prefixed and suffixed attributes in variable declaration") -- ./compiler/lua54.can:35 +else -- ./compiler/lua54.can:35 +t[i][2] = t[1] -- ./compiler/lua54.can:37 +table["insert"](ids, lua(t[i])) -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +return table["concat"](ids, ", ") -- ./compiler/lua54.can:41 end -- ./compiler/lua54.can:41 -local function unindent() -- ./compiler/lua54.can:44 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 -return newline() -- ./compiler/lua54.can:46 -end -- ./compiler/lua54.can:46 -local states = { -- ./compiler/lua54.can:51 -["push"] = {}, -- ./compiler/lua54.can:52 -["destructuring"] = {}, -- ./compiler/lua54.can:53 -["scope"] = {}, -- ./compiler/lua54.can:54 -["macroargs"] = {} -- ./compiler/lua54.can:55 -} -- ./compiler/lua54.can:55 -local function push(name, state) -- ./compiler/lua54.can:58 -table["insert"](states[name], state) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function pop(name) -- ./compiler/lua54.can:63 -table["remove"](states[name]) -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function set(name, state) -- ./compiler/lua54.can:68 -states[name][# states[name]] = state -- ./compiler/lua54.can:69 -return "" -- ./compiler/lua54.can:70 -end -- ./compiler/lua54.can:70 -local function peek(name) -- ./compiler/lua54.can:73 -return states[name][# states[name]] -- ./compiler/lua54.can:74 -end -- ./compiler/lua54.can:74 -local function var(name) -- ./compiler/lua54.can:79 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 -end -- ./compiler/lua54.can:80 -local function tmp() -- ./compiler/lua54.can:84 -local scope = peek("scope") -- ./compiler/lua54.can:85 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 -table["insert"](scope, var) -- ./compiler/lua54.can:87 -return var -- ./compiler/lua54.can:88 -end -- ./compiler/lua54.can:88 -local nomacro = { -- ./compiler/lua54.can:92 -["variables"] = {}, -- ./compiler/lua54.can:92 -["functions"] = {} -- ./compiler/lua54.can:92 -} -- ./compiler/lua54.can:92 -local required = {} -- ./compiler/lua54.can:95 -local requireStr = "" -- ./compiler/lua54.can:96 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 -if not required[req] then -- ./compiler/lua54.can:100 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 -required[req] = true -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -local loop = { -- ./compiler/lua54.can:107 -"While", -- ./compiler/lua54.can:107 -"Repeat", -- ./compiler/lua54.can:107 -"Fornum", -- ./compiler/lua54.can:107 -"Forin", -- ./compiler/lua54.can:107 -"WhileExpr", -- ./compiler/lua54.can:107 -"RepeatExpr", -- ./compiler/lua54.can:107 -"FornumExpr", -- ./compiler/lua54.can:107 -"ForinExpr" -- ./compiler/lua54.can:107 -} -- ./compiler/lua54.can:107 -local func = { -- ./compiler/lua54.can:108 -"Function", -- ./compiler/lua54.can:108 -"TableCompr", -- ./compiler/lua54.can:108 -"DoExpr", -- ./compiler/lua54.can:108 -"WhileExpr", -- ./compiler/lua54.can:108 -"RepeatExpr", -- ./compiler/lua54.can:108 -"IfExpr", -- ./compiler/lua54.can:108 -"FornumExpr", -- ./compiler/lua54.can:108 -"ForinExpr" -- ./compiler/lua54.can:108 -} -- ./compiler/lua54.can:108 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 -local tagsCheck = {} -- ./compiler/lua54.can:113 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 -tagsCheck[tag] = true -- ./compiler/lua54.can:115 -end -- ./compiler/lua54.can:115 -local nofollowCheck = {} -- ./compiler/lua54.can:117 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 -nofollowCheck[tag] = true -- ./compiler/lua54.can:119 -end -- ./compiler/lua54.can:119 -for _, node in ipairs(list) do -- ./compiler/lua54.can:121 -if type(node) == "table" then -- ./compiler/lua54.can:122 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 -return node -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 -if r then -- ./compiler/lua54.can:128 -return r -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -return nil -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 -local tagsCheck = {} -- ./compiler/lua54.can:138 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 -tagsCheck[tag] = true -- ./compiler/lua54.can:140 -end -- ./compiler/lua54.can:140 -local nofollowCheck = {} -- ./compiler/lua54.can:142 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 -nofollowCheck[tag] = true -- ./compiler/lua54.can:144 -end -- ./compiler/lua54.can:144 -local found = {} -- ./compiler/lua54.can:146 -for _, node in ipairs(list) do -- ./compiler/lua54.can:147 -if type(node) == "table" then -- ./compiler/lua54.can:148 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 -table["insert"](found, n) -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 -table["insert"](found, node) -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -return found -- ./compiler/lua54.can:159 -end -- ./compiler/lua54.can:159 -local function all(list, tags) -- ./compiler/lua54.can:163 -for _, node in ipairs(list) do -- ./compiler/lua54.can:164 -local ok = false -- ./compiler/lua54.can:165 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 -if node["tag"] == tag then -- ./compiler/lua54.can:167 -ok = true -- ./compiler/lua54.can:168 -break -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -if not ok then -- ./compiler/lua54.can:172 -return false -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -return true -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -local tags -- ./compiler/lua54.can:180 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 -end -- ./compiler/lua54.can:184 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 -end -- ./compiler/lua54.can:191 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 -end -- ./compiler/lua54.can:194 -local CONTINUE_START = function() -- ./compiler/lua54.can:196 -return "do" .. indent() -- ./compiler/lua54.can:197 -end -- ./compiler/lua54.can:197 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 -end -- ./compiler/lua54.can:200 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 -local vars = {} -- ./compiler/lua54.can:203 -local values = {} -- ./compiler/lua54.can:204 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 -for _, v in ipairs(list) do -- ./compiler/lua54.can:206 -local var, val -- ./compiler/lua54.can:207 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 -var = v -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Index", -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Id", -- ./compiler/lua54.can:210 -list["id"] -- ./compiler/lua54.can:210 -}, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "String", -- ./compiler/lua54.can:210 -v[1] -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 -var = v[2] -- ./compiler/lua54.can:212 -val = { -- ./compiler/lua54.can:213 -["tag"] = "Index", -- ./compiler/lua54.can:213 -{ -- ./compiler/lua54.can:213 -["tag"] = "Id", -- ./compiler/lua54.can:213 -list["id"] -- ./compiler/lua54.can:213 -}, -- ./compiler/lua54.can:213 -v[1] -- ./compiler/lua54.can:213 -} -- ./compiler/lua54.can:213 -else -- ./compiler/lua54.can:213 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 -end -- ./compiler/lua54.can:215 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 -val = { -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["rightOp"], -- ./compiler/lua54.can:218 -var, -- ./compiler/lua54.can:218 -{ -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["leftOp"], -- ./compiler/lua54.can:218 -val, -- ./compiler/lua54.can:218 -var -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 -val = { -- ./compiler/lua54.can:220 -["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["rightOp"], -- ./compiler/lua54.can:220 -var, -- ./compiler/lua54.can:220 -val -- ./compiler/lua54.can:220 -} -- ./compiler/lua54.can:220 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 -val = { -- ./compiler/lua54.can:222 -["tag"] = "Op", -- ./compiler/lua54.can:222 -destructured["leftOp"], -- ./compiler/lua54.can:222 -val, -- ./compiler/lua54.can:222 -var -- ./compiler/lua54.can:222 -} -- ./compiler/lua54.can:222 -end -- ./compiler/lua54.can:222 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -if # vars > 0 then -- ./compiler/lua54.can:228 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 -if newlineAfter then -- ./compiler/lua54.can:230 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 -else -- ./compiler/lua54.can:231 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 -end -- ./compiler/lua54.can:233 -else -- ./compiler/lua54.can:233 -return "" -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -tags = setmetatable({ -- ./compiler/lua54.can:241 -["Block"] = function(t) -- ./compiler/lua54.can:243 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 -hasPush = false -- ./compiler/lua54.can:247 -end -- ./compiler/lua54.can:247 -local r = push("scope", {}) -- ./compiler/lua54.can:249 -if hasPush then -- ./compiler/lua54.can:250 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 -end -- ./compiler/lua54.can:251 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 -end -- ./compiler/lua54.can:254 -if t[# t] then -- ./compiler/lua54.can:256 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 -end -- ./compiler/lua54.can:257 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 -end -- ./compiler/lua54.can:260 -return r .. pop("scope") -- ./compiler/lua54.can:262 -end, -- ./compiler/lua54.can:262 -["Do"] = function(t) -- ./compiler/lua54.can:268 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 -end, -- ./compiler/lua54.can:269 -["Set"] = function(t) -- ./compiler/lua54.can:272 -local expr = t[# t] -- ./compiler/lua54.can:274 -local vars, values = {}, {} -- ./compiler/lua54.can:275 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 -else -- ./compiler/lua54.can:280 -table["insert"](vars, n) -- ./compiler/lua54.can:282 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 -local r = "" -- ./compiler/lua54.can:288 -if # vars > 0 then -- ./compiler/lua54.can:289 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 -end -- ./compiler/lua54.can:290 -if # destructuringVars > 0 then -- ./compiler/lua54.can:292 -local destructured = {} -- ./compiler/lua54.can:293 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 -end -- ./compiler/lua54.can:295 -return r -- ./compiler/lua54.can:297 -elseif # t == 4 then -- ./compiler/lua54.can:298 -if t[3] == "=" then -- ./compiler/lua54.can:299 -local r = "" -- ./compiler/lua54.can:300 -if # vars > 0 then -- ./compiler/lua54.can:301 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 -t[2], -- ./compiler/lua54.can:302 -vars[1], -- ./compiler/lua54.can:302 -{ -- ./compiler/lua54.can:302 -["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[1] -- ./compiler/lua54.can:302 -} -- ./compiler/lua54.can:302 -}, "Op")) -- ./compiler/lua54.can:302 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 -t[2], -- ./compiler/lua54.can:304 -vars[i], -- ./compiler/lua54.can:304 -{ -- ./compiler/lua54.can:304 -["tag"] = "Paren", -- ./compiler/lua54.can:304 -values[i] -- ./compiler/lua54.can:304 -} -- ./compiler/lua54.can:304 -}, "Op")) -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -if # destructuringVars > 0 then -- ./compiler/lua54.can:307 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -return r -- ./compiler/lua54.can:312 -else -- ./compiler/lua54.can:312 -local r = "" -- ./compiler/lua54.can:314 -if # vars > 0 then -- ./compiler/lua54.can:315 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 -t[3], -- ./compiler/lua54.can:316 -{ -- ./compiler/lua54.can:316 -["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[1] -- ./compiler/lua54.can:316 -}, -- ./compiler/lua54.can:316 -vars[1] -- ./compiler/lua54.can:316 -}, "Op")) -- ./compiler/lua54.can:316 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 -t[3], -- ./compiler/lua54.can:318 -{ -- ./compiler/lua54.can:318 -["tag"] = "Paren", -- ./compiler/lua54.can:318 -values[i] -- ./compiler/lua54.can:318 -}, -- ./compiler/lua54.can:318 -vars[i] -- ./compiler/lua54.can:318 -}, "Op")) -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -if # destructuringVars > 0 then -- ./compiler/lua54.can:321 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 -end -- ./compiler/lua54.can:324 -return r -- ./compiler/lua54.can:326 -end -- ./compiler/lua54.can:326 -else -- ./compiler/lua54.can:326 -local r = "" -- ./compiler/lua54.can:329 -if # vars > 0 then -- ./compiler/lua54.can:330 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 -t[2], -- ./compiler/lua54.can:331 -vars[1], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Op", -- ./compiler/lua54.can:331 -t[4], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[1] -- ./compiler/lua54.can:331 -}, -- ./compiler/lua54.can:331 -vars[1] -- ./compiler/lua54.can:331 -} -- ./compiler/lua54.can:331 -}, "Op")) -- ./compiler/lua54.can:331 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 -t[2], -- ./compiler/lua54.can:333 -vars[i], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Op", -- ./compiler/lua54.can:333 -t[4], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Paren", -- ./compiler/lua54.can:333 -values[i] -- ./compiler/lua54.can:333 -}, -- ./compiler/lua54.can:333 -vars[i] -- ./compiler/lua54.can:333 -} -- ./compiler/lua54.can:333 -}, "Op")) -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -if # destructuringVars > 0 then -- ./compiler/lua54.can:336 -local destructured = { -- ./compiler/lua54.can:337 -["rightOp"] = t[2], -- ./compiler/lua54.can:337 -["leftOp"] = t[4] -- ./compiler/lua54.can:337 -} -- ./compiler/lua54.can:337 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 -end -- ./compiler/lua54.can:339 -return r -- ./compiler/lua54.can:341 -end -- ./compiler/lua54.can:341 -end, -- ./compiler/lua54.can:341 -["While"] = function(t) -- ./compiler/lua54.can:345 -local r = "" -- ./compiler/lua54.can:346 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 -if # lets > 0 then -- ./compiler/lua54.can:349 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 -if # lets > 0 then -- ./compiler/lua54.can:356 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 -end -- ./compiler/lua54.can:357 -if hasContinue then -- ./compiler/lua54.can:359 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 -end -- ./compiler/lua54.can:360 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 -if hasContinue then -- ./compiler/lua54.can:363 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 -end -- ./compiler/lua54.can:364 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 -if # lets > 0 then -- ./compiler/lua54.can:367 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 -end -- ./compiler/lua54.can:369 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 -end -- ./compiler/lua54.can:371 -return r -- ./compiler/lua54.can:373 -end, -- ./compiler/lua54.can:373 -["Repeat"] = function(t) -- ./compiler/lua54.can:376 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 -local r = "repeat" .. indent() -- ./compiler/lua54.can:378 -if hasContinue then -- ./compiler/lua54.can:379 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 -end -- ./compiler/lua54.can:380 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 -if hasContinue then -- ./compiler/lua54.can:383 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 -end -- ./compiler/lua54.can:384 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 -return r -- ./compiler/lua54.can:387 -end, -- ./compiler/lua54.can:387 -["If"] = function(t) -- ./compiler/lua54.can:390 -local r = "" -- ./compiler/lua54.can:391 -local toClose = 0 -- ./compiler/lua54.can:392 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 -if # lets > 0 then -- ./compiler/lua54.can:394 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 -toClose = toClose + (1) -- ./compiler/lua54.can:396 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 -if # lets > 0 then -- ./compiler/lua54.can:404 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 -toClose = toClose + (1) -- ./compiler/lua54.can:406 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -else -- ./compiler/lua54.can:408 -r = r .. ("else") -- ./compiler/lua54.can:411 -end -- ./compiler/lua54.can:411 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 -end -- ./compiler/lua54.can:413 -if # t % 2 == 1 then -- ./compiler/lua54.can:415 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 -end -- ./compiler/lua54.can:416 -r = r .. ("end") -- ./compiler/lua54.can:418 -for i = 1, toClose do -- ./compiler/lua54.can:419 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 -end -- ./compiler/lua54.can:420 -return r -- ./compiler/lua54.can:422 -end, -- ./compiler/lua54.can:422 -["Fornum"] = function(t) -- ./compiler/lua54.can:425 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 -if # t == 5 then -- ./compiler/lua54.can:427 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 -if hasContinue then -- ./compiler/lua54.can:430 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 -end -- ./compiler/lua54.can:431 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 -if hasContinue then -- ./compiler/lua54.can:434 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 -end -- ./compiler/lua54.can:435 -return r .. unindent() .. "end" -- ./compiler/lua54.can:437 -else -- ./compiler/lua54.can:437 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 -if hasContinue then -- ./compiler/lua54.can:441 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 -end -- ./compiler/lua54.can:442 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 -if hasContinue then -- ./compiler/lua54.can:445 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 -end -- ./compiler/lua54.can:446 -return r .. unindent() .. "end" -- ./compiler/lua54.can:448 -end -- ./compiler/lua54.can:448 -end, -- ./compiler/lua54.can:448 -["Forin"] = function(t) -- ./compiler/lua54.can:452 -local destructured = {} -- ./compiler/lua54.can:453 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 -if hasContinue then -- ./compiler/lua54.can:456 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 -end -- ./compiler/lua54.can:457 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 -if hasContinue then -- ./compiler/lua54.can:460 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 -end -- ./compiler/lua54.can:461 -return r .. unindent() .. "end" -- ./compiler/lua54.can:463 -end, -- ./compiler/lua54.can:463 -["Local"] = function(t) -- ./compiler/lua54.can:466 -local destructured = {} -- ./compiler/lua54.can:467 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 -if t[2][1] then -- ./compiler/lua54.can:469 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 -end -- ./compiler/lua54.can:470 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 -end, -- ./compiler/lua54.can:472 -["Let"] = function(t) -- ./compiler/lua54.can:475 -local destructured = {} -- ./compiler/lua54.can:476 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 -local r = "local " .. nameList -- ./compiler/lua54.can:478 -if t[2][1] then -- ./compiler/lua54.can:479 -if all(t[2], { -- ./compiler/lua54.can:480 -"Nil", -- ./compiler/lua54.can:480 -"Dots", -- ./compiler/lua54.can:480 -"Boolean", -- ./compiler/lua54.can:480 -"Number", -- ./compiler/lua54.can:480 -"String" -- ./compiler/lua54.can:480 -}) then -- ./compiler/lua54.can:480 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -else -- ./compiler/lua54.can:481 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Localrec"] = function(t) -- ./compiler/lua54.can:489 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Goto"] = function(t) -- ./compiler/lua54.can:493 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 -end, -- ./compiler/lua54.can:494 -["Label"] = function(t) -- ./compiler/lua54.can:497 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 -end, -- ./compiler/lua54.can:498 -["Return"] = function(t) -- ./compiler/lua54.can:501 -local push = peek("push") -- ./compiler/lua54.can:502 -if push then -- ./compiler/lua54.can:503 -local r = "" -- ./compiler/lua54.can:504 -for _, val in ipairs(t) do -- ./compiler/lua54.can:505 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 -end -- ./compiler/lua54.can:506 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 -else -- ./compiler/lua54.can:508 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -end, -- ./compiler/lua54.can:510 -["Push"] = function(t) -- ./compiler/lua54.can:514 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 -r = "" -- ./compiler/lua54.can:516 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 -end -- ./compiler/lua54.can:518 -if t[# t] then -- ./compiler/lua54.can:520 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 -else -- ./compiler/lua54.can:522 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -return r -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Break"] = function() -- ./compiler/lua54.can:530 -return "break" -- ./compiler/lua54.can:531 -end, -- ./compiler/lua54.can:531 -["Continue"] = function() -- ./compiler/lua54.can:534 -return "goto " .. var("continue") -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Nil"] = function() -- ./compiler/lua54.can:542 -return "nil" -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Dots"] = function() -- ./compiler/lua54.can:546 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 -return r -- ./compiler/lua54.can:552 -else -- ./compiler/lua54.can:552 -return "..." -- ./compiler/lua54.can:554 -end -- ./compiler/lua54.can:554 -end, -- ./compiler/lua54.can:554 -["Boolean"] = function(t) -- ./compiler/lua54.can:558 -return tostring(t[1]) -- ./compiler/lua54.can:559 -end, -- ./compiler/lua54.can:559 -["Number"] = function(t) -- ./compiler/lua54.can:562 -return tostring(t[1]) -- ./compiler/lua54.can:563 -end, -- ./compiler/lua54.can:563 -["String"] = function(t) -- ./compiler/lua54.can:566 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 -end, -- ./compiler/lua54.can:567 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 -local r = "(" -- ./compiler/lua54.can:571 -local decl = {} -- ./compiler/lua54.can:572 -if t[1][1] then -- ./compiler/lua54.can:573 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 -r = r .. (id) -- ./compiler/lua54.can:579 -else -- ./compiler/lua54.can:579 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 -r = r .. (", " .. id) -- ./compiler/lua54.can:589 -else -- ./compiler/lua54.can:589 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 -r = r .. (d .. newline()) -- ./compiler/lua54.can:597 -end -- ./compiler/lua54.can:597 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 -end -- ./compiler/lua54.can:600 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 -if hasPush then -- ./compiler/lua54.can:603 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 -else -- ./compiler/lua54.can:604 -push("push", false) -- ./compiler/lua54.can:606 -end -- ./compiler/lua54.can:606 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 -end -- ./compiler/lua54.can:610 -pop("push") -- ./compiler/lua54.can:612 -return r .. unindent() .. "end" -- ./compiler/lua54.can:613 -end, -- ./compiler/lua54.can:613 -["Function"] = function(t) -- ./compiler/lua54.can:615 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 -end, -- ./compiler/lua54.can:616 -["Pair"] = function(t) -- ./compiler/lua54.can:619 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 -end, -- ./compiler/lua54.can:620 -["Table"] = function(t) -- ./compiler/lua54.can:622 -if # t == 0 then -- ./compiler/lua54.can:623 -return "{}" -- ./compiler/lua54.can:624 -elseif # t == 1 then -- ./compiler/lua54.can:625 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 -end -- ./compiler/lua54.can:628 -end, -- ./compiler/lua54.can:628 -["TableCompr"] = function(t) -- ./compiler/lua54.can:632 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 -end, -- ./compiler/lua54.can:633 -["Op"] = function(t) -- ./compiler/lua54.can:636 -local r -- ./compiler/lua54.can:637 -if # t == 2 then -- ./compiler/lua54.can:638 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 -else -- ./compiler/lua54.can:640 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 -end -- ./compiler/lua54.can:642 -else -- ./compiler/lua54.can:642 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 -else -- ./compiler/lua54.can:646 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -return r -- ./compiler/lua54.can:651 -end, -- ./compiler/lua54.can:651 -["Paren"] = function(t) -- ./compiler/lua54.can:654 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 -end, -- ./compiler/lua54.can:655 -["MethodStub"] = function(t) -- ./compiler/lua54.can:658 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 -end, -- ./compiler/lua54.can:664 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 -end, -- ./compiler/lua54.can:674 -["LetExpr"] = function(t) -- ./compiler/lua54.can:681 -return lua(t[1][1]) -- ./compiler/lua54.can:682 -end, -- ./compiler/lua54.can:682 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 -local r = "(function()" .. indent() -- ./compiler/lua54.can:688 -if hasPush then -- ./compiler/lua54.can:689 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 -else -- ./compiler/lua54.can:690 -push("push", false) -- ./compiler/lua54.can:692 -end -- ./compiler/lua54.can:692 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 -if hasPush then -- ./compiler/lua54.can:695 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 -end -- ./compiler/lua54.can:696 -pop("push") -- ./compiler/lua54.can:698 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 -return r -- ./compiler/lua54.can:700 -end, -- ./compiler/lua54.can:700 -["DoExpr"] = function(t) -- ./compiler/lua54.can:703 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 -end -- ./compiler/lua54.can:705 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 -end, -- ./compiler/lua54.can:707 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 -end, -- ./compiler/lua54.can:711 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 -end, -- ./compiler/lua54.can:715 -["IfExpr"] = function(t) -- ./compiler/lua54.can:718 -for i = 2, # t do -- ./compiler/lua54.can:719 -local block = t[i] -- ./compiler/lua54.can:720 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 -end, -- ./compiler/lua54.can:725 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 -end, -- ./compiler/lua54.can:729 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["Call"] = function(t) -- ./compiler/lua54.can:739 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 -local replacement = macro["replacement"] -- ./compiler/lua54.can:744 -local r -- ./compiler/lua54.can:745 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 -if type(replacement) == "function" then -- ./compiler/lua54.can:747 -local args = {} -- ./compiler/lua54.can:748 -for i = 2, # t do -- ./compiler/lua54.can:749 -table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 -end -- ./compiler/lua54.can:750 -r = replacement(unpack(args)) -- ./compiler/lua54.can:752 -else -- ./compiler/lua54.can:752 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 -macroargs["..."] = (function() -- ./compiler/lua54.can:757 -local self = {} -- ./compiler/lua54.can:757 -for j = i + 1, # t do -- ./compiler/lua54.can:757 -self[#self+1] = t[j] -- ./compiler/lua54.can:757 -end -- ./compiler/lua54.can:757 -return self -- ./compiler/lua54.can:757 -end)() -- ./compiler/lua54.can:757 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 -if t[i + 1] == nil then -- ./compiler/lua54.can:759 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 -end -- ./compiler/lua54.can:760 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 -else -- ./compiler/lua54.can:762 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -push("macroargs", macroargs) -- ./compiler/lua54.can:767 -r = lua(replacement) -- ./compiler/lua54.can:768 -pop("macroargs") -- ./compiler/lua54.can:769 -end -- ./compiler/lua54.can:769 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 -return r -- ./compiler/lua54.can:772 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 -else -- ./compiler/lua54.can:775 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 -end -- ./compiler/lua54.can:777 -else -- ./compiler/lua54.can:777 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 -end -- ./compiler/lua54.can:780 -end, -- ./compiler/lua54.can:780 -["SafeCall"] = function(t) -- ./compiler/lua54.can:784 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 -else -- ./compiler/lua54.can:786 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 -end -- ./compiler/lua54.can:788 -end, -- ./compiler/lua54.can:788 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 -if start == nil then start = 1 end -- ./compiler/lua54.can:793 -local r -- ./compiler/lua54.can:794 -if t[start] then -- ./compiler/lua54.can:795 -r = lua(t[start]) -- ./compiler/lua54.can:796 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 -end -- ./compiler/lua54.can:798 -else -- ./compiler/lua54.can:798 -r = "" -- ./compiler/lua54.can:801 -end -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:803 -end, -- ./compiler/lua54.can:803 -["Id"] = function(t) -- ./compiler/lua54.can:806 -local r = t[1] -- ./compiler/lua54.can:807 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 -r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 -local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 -if type(macro) == "function" then -- ./compiler/lua54.can:815 -r = macro() -- ./compiler/lua54.can:816 -else -- ./compiler/lua54.can:816 -r = lua(macro) -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 -end -- ./compiler/lua54.can:821 -return r -- ./compiler/lua54.can:823 -end, -- ./compiler/lua54.can:823 -["AttributeId"] = function(t) -- ./compiler/lua54.can:826 -if t[2] then -- ./compiler/lua54.can:827 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 -else -- ./compiler/lua54.can:828 -return t[1] -- ./compiler/lua54.can:830 -end -- ./compiler/lua54.can:830 -end, -- ./compiler/lua54.can:830 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 -if t["id"] then -- ./compiler/lua54.can:835 -return t["id"] -- ./compiler/lua54.can:836 -else -- ./compiler/lua54.can:836 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 -for j = 1, # t, 1 do -- ./compiler/lua54.can:840 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 -end -- ./compiler/lua54.can:841 -table["insert"](d, vars) -- ./compiler/lua54.can:843 -t["id"] = vars["id"] -- ./compiler/lua54.can:844 -return vars["id"] -- ./compiler/lua54.can:845 -end -- ./compiler/lua54.can:845 -end, -- ./compiler/lua54.can:845 -["Index"] = function(t) -- ./compiler/lua54.can:849 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 -else -- ./compiler/lua54.can:851 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 -end -- ./compiler/lua54.can:853 -end, -- ./compiler/lua54.can:853 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 -local l = {} -- ./compiler/lua54.can:859 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 -table["insert"](l, 1, t) -- ./compiler/lua54.can:861 -t = t[1] -- ./compiler/lua54.can:862 -end -- ./compiler/lua54.can:862 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 -for _, e in ipairs(l) do -- ./compiler/lua54.can:865 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 -else -- ./compiler/lua54.can:868 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 -return r -- ./compiler/lua54.can:874 -else -- ./compiler/lua54.can:874 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 -end -- ./compiler/lua54.can:876 -end, -- ./compiler/lua54.can:876 -["_opid"] = { -- ./compiler/lua54.can:881 -["add"] = "+", -- ./compiler/lua54.can:882 -["sub"] = "-", -- ./compiler/lua54.can:882 -["mul"] = "*", -- ./compiler/lua54.can:882 -["div"] = "/", -- ./compiler/lua54.can:882 -["idiv"] = "//", -- ./compiler/lua54.can:883 -["mod"] = "%", -- ./compiler/lua54.can:883 -["pow"] = "^", -- ./compiler/lua54.can:883 -["concat"] = "..", -- ./compiler/lua54.can:883 -["band"] = "&", -- ./compiler/lua54.can:884 -["bor"] = "|", -- ./compiler/lua54.can:884 -["bxor"] = "~", -- ./compiler/lua54.can:884 -["shl"] = "<<", -- ./compiler/lua54.can:884 -["shr"] = ">>", -- ./compiler/lua54.can:884 -["eq"] = "==", -- ./compiler/lua54.can:885 -["ne"] = "~=", -- ./compiler/lua54.can:885 -["lt"] = "<", -- ./compiler/lua54.can:885 -["gt"] = ">", -- ./compiler/lua54.can:885 -["le"] = "<=", -- ./compiler/lua54.can:885 -["ge"] = ">=", -- ./compiler/lua54.can:885 -["and"] = "and", -- ./compiler/lua54.can:886 -["or"] = "or", -- ./compiler/lua54.can:886 -["unm"] = "-", -- ./compiler/lua54.can:886 -["len"] = "#", -- ./compiler/lua54.can:886 -["bnot"] = "~", -- ./compiler/lua54.can:886 -["not"] = "not" -- ./compiler/lua54.can:886 -} -- ./compiler/lua54.can:886 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 -end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -3175,6 +4342,9 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua53.can:11 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:12 +end -- ./compiler/lua53.can:12 targetName = "Lua 5.2" -- ./compiler/lua52.can:1 APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 @@ -3200,14 +4370,17 @@ end -- ./compiler/lua52.can:23 tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 end -- ./compiler/lua52.can:26 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 -return requireStr .. code -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -local lua54 = _() or lua54 -- ./compiler/lua54.can:902 -return lua54 -- ./compiler/lua53.can:18 -end -- ./compiler/lua53.can:18 -local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +return lua55 -- ./compiler/lua54.can:50 +end -- ./compiler/lua54.can:50 +local lua54 = _() or lua54 -- ./compiler/lua54.can:54 +return lua54 -- ./compiler/lua53.can:21 +end -- ./compiler/lua53.can:21 +local lua53 = _() or lua53 -- ./compiler/lua53.can:25 return lua53 -- ./compiler/lua52.can:35 end -- ./compiler/lua52.can:35 local lua52 = _() or lua52 -- ./compiler/lua52.can:39 @@ -3216,933 +4389,998 @@ local function _() -- ./compiler/lua52.can:43 local function _() -- ./compiler/lua52.can:45 local function _() -- ./compiler/lua52.can:47 local function _() -- ./compiler/lua52.can:49 -local util = require("candran.util") -- ./compiler/lua54.can:1 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 -return function(code, ast, options, macros) -- ./compiler/lua54.can:7 -if macros == nil then macros = { -- ./compiler/lua54.can:7 -["functions"] = {}, -- ./compiler/lua54.can:7 -["variables"] = {} -- ./compiler/lua54.can:7 -} end -- ./compiler/lua54.can:7 -local lastInputPos = 1 -- ./compiler/lua54.can:9 -local prevLinePos = 1 -- ./compiler/lua54.can:10 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 -local lastLine = 1 -- ./compiler/lua54.can:12 -local indentLevel = 0 -- ./compiler/lua54.can:15 -local function newline() -- ./compiler/lua54.can:17 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 -if options["mapLines"] then -- ./compiler/lua54.can:19 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 +local function _() -- ./compiler/lua52.can:51 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:21 -if source and line then -- ./compiler/lua54.can:23 -lastSource = source -- ./compiler/lua54.can:24 -lastLine = tonumber(line) -- ./compiler/lua54.can:25 -else -- ./compiler/lua54.can:25 +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:27 -lastLine = lastLine + (1) -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -prevLinePos = lastInputPos -- ./compiler/lua54.can:32 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 -end -- ./compiler/lua54.can:34 -return r -- ./compiler/lua54.can:36 -end -- ./compiler/lua54.can:36 -local function indent() -- ./compiler/lua54.can:39 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 -return newline() -- ./compiler/lua54.can:41 +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +tags["Global"] = function(t) -- ./compiler/lua54.can:4 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:5 +end -- ./compiler/lua54.can:5 +tags["Globalrec"] = function(t) -- ./compiler/lua54.can:7 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:8 +end -- ./compiler/lua54.can:8 +tags["GlobalAll"] = function(t) -- ./compiler/lua54.can:10 +if # t == 1 then -- ./compiler/lua54.can:11 +error("target " .. targetName .. " does not support collective global variable declaration") -- ./compiler/lua54.can:12 +else -- ./compiler/lua54.can:12 +return "" -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +tags["_functionParameter"]["ParDots"] = function(t, decl) -- ./compiler/lua54.can:19 +if # t == 1 then -- ./compiler/lua54.can:20 +local id = lua(t[1]) -- ./compiler/lua54.can:21 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:22 +table["insert"](decl, "local " .. id .. " = { ... }") -- ./compiler/lua54.can:23 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +return "..." -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua54.can:31 +local ids = {} -- ./compiler/lua54.can:32 +for i = 2, # t, 1 do -- ./compiler/lua54.can:33 +if t[i][2] then -- ./compiler/lua54.can:34 +error("target " .. targetName .. " does not support combining prefixed and suffixed attributes in variable declaration") -- ./compiler/lua54.can:35 +else -- ./compiler/lua54.can:35 +t[i][2] = t[1] -- ./compiler/lua54.can:37 +table["insert"](ids, lua(t[i])) -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +return table["concat"](ids, ", ") -- ./compiler/lua54.can:41 end -- ./compiler/lua54.can:41 -local function unindent() -- ./compiler/lua54.can:44 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 -return newline() -- ./compiler/lua54.can:46 -end -- ./compiler/lua54.can:46 -local states = { -- ./compiler/lua54.can:51 -["push"] = {}, -- ./compiler/lua54.can:52 -["destructuring"] = {}, -- ./compiler/lua54.can:53 -["scope"] = {}, -- ./compiler/lua54.can:54 -["macroargs"] = {} -- ./compiler/lua54.can:55 -} -- ./compiler/lua54.can:55 -local function push(name, state) -- ./compiler/lua54.can:58 -table["insert"](states[name], state) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function pop(name) -- ./compiler/lua54.can:63 -table["remove"](states[name]) -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function set(name, state) -- ./compiler/lua54.can:68 -states[name][# states[name]] = state -- ./compiler/lua54.can:69 -return "" -- ./compiler/lua54.can:70 -end -- ./compiler/lua54.can:70 -local function peek(name) -- ./compiler/lua54.can:73 -return states[name][# states[name]] -- ./compiler/lua54.can:74 -end -- ./compiler/lua54.can:74 -local function var(name) -- ./compiler/lua54.can:79 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 -end -- ./compiler/lua54.can:80 -local function tmp() -- ./compiler/lua54.can:84 -local scope = peek("scope") -- ./compiler/lua54.can:85 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 -table["insert"](scope, var) -- ./compiler/lua54.can:87 -return var -- ./compiler/lua54.can:88 -end -- ./compiler/lua54.can:88 -local nomacro = { -- ./compiler/lua54.can:92 -["variables"] = {}, -- ./compiler/lua54.can:92 -["functions"] = {} -- ./compiler/lua54.can:92 -} -- ./compiler/lua54.can:92 -local required = {} -- ./compiler/lua54.can:95 -local requireStr = "" -- ./compiler/lua54.can:96 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 -if not required[req] then -- ./compiler/lua54.can:100 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 -required[req] = true -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -local loop = { -- ./compiler/lua54.can:107 -"While", -- ./compiler/lua54.can:107 -"Repeat", -- ./compiler/lua54.can:107 -"Fornum", -- ./compiler/lua54.can:107 -"Forin", -- ./compiler/lua54.can:107 -"WhileExpr", -- ./compiler/lua54.can:107 -"RepeatExpr", -- ./compiler/lua54.can:107 -"FornumExpr", -- ./compiler/lua54.can:107 -"ForinExpr" -- ./compiler/lua54.can:107 -} -- ./compiler/lua54.can:107 -local func = { -- ./compiler/lua54.can:108 -"Function", -- ./compiler/lua54.can:108 -"TableCompr", -- ./compiler/lua54.can:108 -"DoExpr", -- ./compiler/lua54.can:108 -"WhileExpr", -- ./compiler/lua54.can:108 -"RepeatExpr", -- ./compiler/lua54.can:108 -"IfExpr", -- ./compiler/lua54.can:108 -"FornumExpr", -- ./compiler/lua54.can:108 -"ForinExpr" -- ./compiler/lua54.can:108 -} -- ./compiler/lua54.can:108 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 -local tagsCheck = {} -- ./compiler/lua54.can:113 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 -tagsCheck[tag] = true -- ./compiler/lua54.can:115 -end -- ./compiler/lua54.can:115 -local nofollowCheck = {} -- ./compiler/lua54.can:117 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 -nofollowCheck[tag] = true -- ./compiler/lua54.can:119 -end -- ./compiler/lua54.can:119 -for _, node in ipairs(list) do -- ./compiler/lua54.can:121 -if type(node) == "table" then -- ./compiler/lua54.can:122 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 -return node -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 -if r then -- ./compiler/lua54.can:128 -return r -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -return nil -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 -local tagsCheck = {} -- ./compiler/lua54.can:138 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 -tagsCheck[tag] = true -- ./compiler/lua54.can:140 -end -- ./compiler/lua54.can:140 -local nofollowCheck = {} -- ./compiler/lua54.can:142 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 -nofollowCheck[tag] = true -- ./compiler/lua54.can:144 -end -- ./compiler/lua54.can:144 -local found = {} -- ./compiler/lua54.can:146 -for _, node in ipairs(list) do -- ./compiler/lua54.can:147 -if type(node) == "table" then -- ./compiler/lua54.can:148 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 -table["insert"](found, n) -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 -table["insert"](found, node) -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -return found -- ./compiler/lua54.can:159 -end -- ./compiler/lua54.can:159 -local function all(list, tags) -- ./compiler/lua54.can:163 -for _, node in ipairs(list) do -- ./compiler/lua54.can:164 -local ok = false -- ./compiler/lua54.can:165 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 -if node["tag"] == tag then -- ./compiler/lua54.can:167 -ok = true -- ./compiler/lua54.can:168 -break -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -if not ok then -- ./compiler/lua54.can:172 -return false -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -return true -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -local tags -- ./compiler/lua54.can:180 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 -end -- ./compiler/lua54.can:184 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 -end -- ./compiler/lua54.can:191 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 -end -- ./compiler/lua54.can:194 -local CONTINUE_START = function() -- ./compiler/lua54.can:196 -return "do" .. indent() -- ./compiler/lua54.can:197 -end -- ./compiler/lua54.can:197 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 -end -- ./compiler/lua54.can:200 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 -local vars = {} -- ./compiler/lua54.can:203 -local values = {} -- ./compiler/lua54.can:204 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 -for _, v in ipairs(list) do -- ./compiler/lua54.can:206 -local var, val -- ./compiler/lua54.can:207 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 -var = v -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Index", -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Id", -- ./compiler/lua54.can:210 -list["id"] -- ./compiler/lua54.can:210 -}, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "String", -- ./compiler/lua54.can:210 -v[1] -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 -var = v[2] -- ./compiler/lua54.can:212 -val = { -- ./compiler/lua54.can:213 -["tag"] = "Index", -- ./compiler/lua54.can:213 -{ -- ./compiler/lua54.can:213 -["tag"] = "Id", -- ./compiler/lua54.can:213 -list["id"] -- ./compiler/lua54.can:213 -}, -- ./compiler/lua54.can:213 -v[1] -- ./compiler/lua54.can:213 -} -- ./compiler/lua54.can:213 -else -- ./compiler/lua54.can:213 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 -end -- ./compiler/lua54.can:215 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 -val = { -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["rightOp"], -- ./compiler/lua54.can:218 -var, -- ./compiler/lua54.can:218 -{ -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["leftOp"], -- ./compiler/lua54.can:218 -val, -- ./compiler/lua54.can:218 -var -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 -val = { -- ./compiler/lua54.can:220 -["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["rightOp"], -- ./compiler/lua54.can:220 -var, -- ./compiler/lua54.can:220 -val -- ./compiler/lua54.can:220 -} -- ./compiler/lua54.can:220 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 -val = { -- ./compiler/lua54.can:222 -["tag"] = "Op", -- ./compiler/lua54.can:222 -destructured["leftOp"], -- ./compiler/lua54.can:222 -val, -- ./compiler/lua54.can:222 -var -- ./compiler/lua54.can:222 -} -- ./compiler/lua54.can:222 -end -- ./compiler/lua54.can:222 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -if # vars > 0 then -- ./compiler/lua54.can:228 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 -if newlineAfter then -- ./compiler/lua54.can:230 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 -else -- ./compiler/lua54.can:231 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 -end -- ./compiler/lua54.can:233 -else -- ./compiler/lua54.can:233 -return "" -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -tags = setmetatable({ -- ./compiler/lua54.can:241 -["Block"] = function(t) -- ./compiler/lua54.can:243 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 -hasPush = false -- ./compiler/lua54.can:247 -end -- ./compiler/lua54.can:247 -local r = push("scope", {}) -- ./compiler/lua54.can:249 -if hasPush then -- ./compiler/lua54.can:250 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 -end -- ./compiler/lua54.can:251 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 -end -- ./compiler/lua54.can:254 -if t[# t] then -- ./compiler/lua54.can:256 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 -end -- ./compiler/lua54.can:257 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 -end -- ./compiler/lua54.can:260 -return r .. pop("scope") -- ./compiler/lua54.can:262 -end, -- ./compiler/lua54.can:262 -["Do"] = function(t) -- ./compiler/lua54.can:268 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 -end, -- ./compiler/lua54.can:269 -["Set"] = function(t) -- ./compiler/lua54.can:272 -local expr = t[# t] -- ./compiler/lua54.can:274 -local vars, values = {}, {} -- ./compiler/lua54.can:275 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 -else -- ./compiler/lua54.can:280 -table["insert"](vars, n) -- ./compiler/lua54.can:282 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 -local r = "" -- ./compiler/lua54.can:288 -if # vars > 0 then -- ./compiler/lua54.can:289 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 -end -- ./compiler/lua54.can:290 -if # destructuringVars > 0 then -- ./compiler/lua54.can:292 -local destructured = {} -- ./compiler/lua54.can:293 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 -end -- ./compiler/lua54.can:295 -return r -- ./compiler/lua54.can:297 -elseif # t == 4 then -- ./compiler/lua54.can:298 -if t[3] == "=" then -- ./compiler/lua54.can:299 -local r = "" -- ./compiler/lua54.can:300 -if # vars > 0 then -- ./compiler/lua54.can:301 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 -t[2], -- ./compiler/lua54.can:302 -vars[1], -- ./compiler/lua54.can:302 -{ -- ./compiler/lua54.can:302 -["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[1] -- ./compiler/lua54.can:302 -} -- ./compiler/lua54.can:302 -}, "Op")) -- ./compiler/lua54.can:302 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 -t[2], -- ./compiler/lua54.can:304 -vars[i], -- ./compiler/lua54.can:304 -{ -- ./compiler/lua54.can:304 -["tag"] = "Paren", -- ./compiler/lua54.can:304 -values[i] -- ./compiler/lua54.can:304 -} -- ./compiler/lua54.can:304 -}, "Op")) -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -if # destructuringVars > 0 then -- ./compiler/lua54.can:307 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -return r -- ./compiler/lua54.can:312 -else -- ./compiler/lua54.can:312 -local r = "" -- ./compiler/lua54.can:314 -if # vars > 0 then -- ./compiler/lua54.can:315 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 -t[3], -- ./compiler/lua54.can:316 -{ -- ./compiler/lua54.can:316 -["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[1] -- ./compiler/lua54.can:316 -}, -- ./compiler/lua54.can:316 -vars[1] -- ./compiler/lua54.can:316 -}, "Op")) -- ./compiler/lua54.can:316 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 -t[3], -- ./compiler/lua54.can:318 -{ -- ./compiler/lua54.can:318 -["tag"] = "Paren", -- ./compiler/lua54.can:318 -values[i] -- ./compiler/lua54.can:318 -}, -- ./compiler/lua54.can:318 -vars[i] -- ./compiler/lua54.can:318 -}, "Op")) -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -if # destructuringVars > 0 then -- ./compiler/lua54.can:321 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 -end -- ./compiler/lua54.can:324 -return r -- ./compiler/lua54.can:326 -end -- ./compiler/lua54.can:326 -else -- ./compiler/lua54.can:326 -local r = "" -- ./compiler/lua54.can:329 -if # vars > 0 then -- ./compiler/lua54.can:330 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 -t[2], -- ./compiler/lua54.can:331 -vars[1], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Op", -- ./compiler/lua54.can:331 -t[4], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[1] -- ./compiler/lua54.can:331 -}, -- ./compiler/lua54.can:331 -vars[1] -- ./compiler/lua54.can:331 -} -- ./compiler/lua54.can:331 -}, "Op")) -- ./compiler/lua54.can:331 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 -t[2], -- ./compiler/lua54.can:333 -vars[i], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Op", -- ./compiler/lua54.can:333 -t[4], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Paren", -- ./compiler/lua54.can:333 -values[i] -- ./compiler/lua54.can:333 -}, -- ./compiler/lua54.can:333 -vars[i] -- ./compiler/lua54.can:333 -} -- ./compiler/lua54.can:333 -}, "Op")) -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -if # destructuringVars > 0 then -- ./compiler/lua54.can:336 -local destructured = { -- ./compiler/lua54.can:337 -["rightOp"] = t[2], -- ./compiler/lua54.can:337 -["leftOp"] = t[4] -- ./compiler/lua54.can:337 -} -- ./compiler/lua54.can:337 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 -end -- ./compiler/lua54.can:339 -return r -- ./compiler/lua54.can:341 -end -- ./compiler/lua54.can:341 -end, -- ./compiler/lua54.can:341 -["While"] = function(t) -- ./compiler/lua54.can:345 -local r = "" -- ./compiler/lua54.can:346 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 -if # lets > 0 then -- ./compiler/lua54.can:349 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 -if # lets > 0 then -- ./compiler/lua54.can:356 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 -end -- ./compiler/lua54.can:357 -if hasContinue then -- ./compiler/lua54.can:359 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 -end -- ./compiler/lua54.can:360 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 -if hasContinue then -- ./compiler/lua54.can:363 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 -end -- ./compiler/lua54.can:364 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 -if # lets > 0 then -- ./compiler/lua54.can:367 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 -end -- ./compiler/lua54.can:369 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 -end -- ./compiler/lua54.can:371 -return r -- ./compiler/lua54.can:373 -end, -- ./compiler/lua54.can:373 -["Repeat"] = function(t) -- ./compiler/lua54.can:376 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 -local r = "repeat" .. indent() -- ./compiler/lua54.can:378 -if hasContinue then -- ./compiler/lua54.can:379 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 -end -- ./compiler/lua54.can:380 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 -if hasContinue then -- ./compiler/lua54.can:383 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 -end -- ./compiler/lua54.can:384 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 -return r -- ./compiler/lua54.can:387 -end, -- ./compiler/lua54.can:387 -["If"] = function(t) -- ./compiler/lua54.can:390 -local r = "" -- ./compiler/lua54.can:391 -local toClose = 0 -- ./compiler/lua54.can:392 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 -if # lets > 0 then -- ./compiler/lua54.can:394 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 -toClose = toClose + (1) -- ./compiler/lua54.can:396 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 -if # lets > 0 then -- ./compiler/lua54.can:404 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 -toClose = toClose + (1) -- ./compiler/lua54.can:406 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -else -- ./compiler/lua54.can:408 -r = r .. ("else") -- ./compiler/lua54.can:411 -end -- ./compiler/lua54.can:411 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 -end -- ./compiler/lua54.can:413 -if # t % 2 == 1 then -- ./compiler/lua54.can:415 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 -end -- ./compiler/lua54.can:416 -r = r .. ("end") -- ./compiler/lua54.can:418 -for i = 1, toClose do -- ./compiler/lua54.can:419 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 -end -- ./compiler/lua54.can:420 -return r -- ./compiler/lua54.can:422 -end, -- ./compiler/lua54.can:422 -["Fornum"] = function(t) -- ./compiler/lua54.can:425 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 -if # t == 5 then -- ./compiler/lua54.can:427 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 -if hasContinue then -- ./compiler/lua54.can:430 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 -end -- ./compiler/lua54.can:431 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 -if hasContinue then -- ./compiler/lua54.can:434 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 -end -- ./compiler/lua54.can:435 -return r .. unindent() .. "end" -- ./compiler/lua54.can:437 -else -- ./compiler/lua54.can:437 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 -if hasContinue then -- ./compiler/lua54.can:441 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 -end -- ./compiler/lua54.can:442 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 -if hasContinue then -- ./compiler/lua54.can:445 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 -end -- ./compiler/lua54.can:446 -return r .. unindent() .. "end" -- ./compiler/lua54.can:448 -end -- ./compiler/lua54.can:448 -end, -- ./compiler/lua54.can:448 -["Forin"] = function(t) -- ./compiler/lua54.can:452 -local destructured = {} -- ./compiler/lua54.can:453 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 -if hasContinue then -- ./compiler/lua54.can:456 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 -end -- ./compiler/lua54.can:457 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 -if hasContinue then -- ./compiler/lua54.can:460 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 -end -- ./compiler/lua54.can:461 -return r .. unindent() .. "end" -- ./compiler/lua54.can:463 -end, -- ./compiler/lua54.can:463 -["Local"] = function(t) -- ./compiler/lua54.can:466 -local destructured = {} -- ./compiler/lua54.can:467 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 -if t[2][1] then -- ./compiler/lua54.can:469 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 -end -- ./compiler/lua54.can:470 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 -end, -- ./compiler/lua54.can:472 -["Let"] = function(t) -- ./compiler/lua54.can:475 -local destructured = {} -- ./compiler/lua54.can:476 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 -local r = "local " .. nameList -- ./compiler/lua54.can:478 -if t[2][1] then -- ./compiler/lua54.can:479 -if all(t[2], { -- ./compiler/lua54.can:480 -"Nil", -- ./compiler/lua54.can:480 -"Dots", -- ./compiler/lua54.can:480 -"Boolean", -- ./compiler/lua54.can:480 -"Number", -- ./compiler/lua54.can:480 -"String" -- ./compiler/lua54.can:480 -}) then -- ./compiler/lua54.can:480 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -else -- ./compiler/lua54.can:481 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Localrec"] = function(t) -- ./compiler/lua54.can:489 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Goto"] = function(t) -- ./compiler/lua54.can:493 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 -end, -- ./compiler/lua54.can:494 -["Label"] = function(t) -- ./compiler/lua54.can:497 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 -end, -- ./compiler/lua54.can:498 -["Return"] = function(t) -- ./compiler/lua54.can:501 -local push = peek("push") -- ./compiler/lua54.can:502 -if push then -- ./compiler/lua54.can:503 -local r = "" -- ./compiler/lua54.can:504 -for _, val in ipairs(t) do -- ./compiler/lua54.can:505 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 -end -- ./compiler/lua54.can:506 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 -else -- ./compiler/lua54.can:508 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -end, -- ./compiler/lua54.can:510 -["Push"] = function(t) -- ./compiler/lua54.can:514 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 -r = "" -- ./compiler/lua54.can:516 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 -end -- ./compiler/lua54.can:518 -if t[# t] then -- ./compiler/lua54.can:520 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 -else -- ./compiler/lua54.can:522 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -return r -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Break"] = function() -- ./compiler/lua54.can:530 -return "break" -- ./compiler/lua54.can:531 -end, -- ./compiler/lua54.can:531 -["Continue"] = function() -- ./compiler/lua54.can:534 -return "goto " .. var("continue") -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Nil"] = function() -- ./compiler/lua54.can:542 -return "nil" -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Dots"] = function() -- ./compiler/lua54.can:546 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 -return r -- ./compiler/lua54.can:552 -else -- ./compiler/lua54.can:552 -return "..." -- ./compiler/lua54.can:554 -end -- ./compiler/lua54.can:554 -end, -- ./compiler/lua54.can:554 -["Boolean"] = function(t) -- ./compiler/lua54.can:558 -return tostring(t[1]) -- ./compiler/lua54.can:559 -end, -- ./compiler/lua54.can:559 -["Number"] = function(t) -- ./compiler/lua54.can:562 -return tostring(t[1]) -- ./compiler/lua54.can:563 -end, -- ./compiler/lua54.can:563 -["String"] = function(t) -- ./compiler/lua54.can:566 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 -end, -- ./compiler/lua54.can:567 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 -local r = "(" -- ./compiler/lua54.can:571 -local decl = {} -- ./compiler/lua54.can:572 -if t[1][1] then -- ./compiler/lua54.can:573 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 -r = r .. (id) -- ./compiler/lua54.can:579 -else -- ./compiler/lua54.can:579 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 -r = r .. (", " .. id) -- ./compiler/lua54.can:589 -else -- ./compiler/lua54.can:589 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 -r = r .. (d .. newline()) -- ./compiler/lua54.can:597 -end -- ./compiler/lua54.can:597 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 -end -- ./compiler/lua54.can:600 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 -if hasPush then -- ./compiler/lua54.can:603 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 -else -- ./compiler/lua54.can:604 -push("push", false) -- ./compiler/lua54.can:606 -end -- ./compiler/lua54.can:606 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 -end -- ./compiler/lua54.can:610 -pop("push") -- ./compiler/lua54.can:612 -return r .. unindent() .. "end" -- ./compiler/lua54.can:613 -end, -- ./compiler/lua54.can:613 -["Function"] = function(t) -- ./compiler/lua54.can:615 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 -end, -- ./compiler/lua54.can:616 -["Pair"] = function(t) -- ./compiler/lua54.can:619 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 -end, -- ./compiler/lua54.can:620 -["Table"] = function(t) -- ./compiler/lua54.can:622 -if # t == 0 then -- ./compiler/lua54.can:623 -return "{}" -- ./compiler/lua54.can:624 -elseif # t == 1 then -- ./compiler/lua54.can:625 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 -end -- ./compiler/lua54.can:628 -end, -- ./compiler/lua54.can:628 -["TableCompr"] = function(t) -- ./compiler/lua54.can:632 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 -end, -- ./compiler/lua54.can:633 -["Op"] = function(t) -- ./compiler/lua54.can:636 -local r -- ./compiler/lua54.can:637 -if # t == 2 then -- ./compiler/lua54.can:638 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 -else -- ./compiler/lua54.can:640 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 -end -- ./compiler/lua54.can:642 -else -- ./compiler/lua54.can:642 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 -else -- ./compiler/lua54.can:646 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -return r -- ./compiler/lua54.can:651 -end, -- ./compiler/lua54.can:651 -["Paren"] = function(t) -- ./compiler/lua54.can:654 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 -end, -- ./compiler/lua54.can:655 -["MethodStub"] = function(t) -- ./compiler/lua54.can:658 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 -end, -- ./compiler/lua54.can:664 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 -end, -- ./compiler/lua54.can:674 -["LetExpr"] = function(t) -- ./compiler/lua54.can:681 -return lua(t[1][1]) -- ./compiler/lua54.can:682 -end, -- ./compiler/lua54.can:682 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 -local r = "(function()" .. indent() -- ./compiler/lua54.can:688 -if hasPush then -- ./compiler/lua54.can:689 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 -else -- ./compiler/lua54.can:690 -push("push", false) -- ./compiler/lua54.can:692 -end -- ./compiler/lua54.can:692 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 -if hasPush then -- ./compiler/lua54.can:695 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 -end -- ./compiler/lua54.can:696 -pop("push") -- ./compiler/lua54.can:698 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 -return r -- ./compiler/lua54.can:700 -end, -- ./compiler/lua54.can:700 -["DoExpr"] = function(t) -- ./compiler/lua54.can:703 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 -end -- ./compiler/lua54.can:705 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 -end, -- ./compiler/lua54.can:707 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 -end, -- ./compiler/lua54.can:711 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 -end, -- ./compiler/lua54.can:715 -["IfExpr"] = function(t) -- ./compiler/lua54.can:718 -for i = 2, # t do -- ./compiler/lua54.can:719 -local block = t[i] -- ./compiler/lua54.can:720 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 -end, -- ./compiler/lua54.can:725 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 -end, -- ./compiler/lua54.can:729 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["Call"] = function(t) -- ./compiler/lua54.can:739 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 -local replacement = macro["replacement"] -- ./compiler/lua54.can:744 -local r -- ./compiler/lua54.can:745 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 -if type(replacement) == "function" then -- ./compiler/lua54.can:747 -local args = {} -- ./compiler/lua54.can:748 -for i = 2, # t do -- ./compiler/lua54.can:749 -table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 -end -- ./compiler/lua54.can:750 -r = replacement(unpack(args)) -- ./compiler/lua54.can:752 -else -- ./compiler/lua54.can:752 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 -macroargs["..."] = (function() -- ./compiler/lua54.can:757 -local self = {} -- ./compiler/lua54.can:757 -for j = i + 1, # t do -- ./compiler/lua54.can:757 -self[#self+1] = t[j] -- ./compiler/lua54.can:757 -end -- ./compiler/lua54.can:757 -return self -- ./compiler/lua54.can:757 -end)() -- ./compiler/lua54.can:757 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 -if t[i + 1] == nil then -- ./compiler/lua54.can:759 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 -end -- ./compiler/lua54.can:760 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 -else -- ./compiler/lua54.can:762 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -push("macroargs", macroargs) -- ./compiler/lua54.can:767 -r = lua(replacement) -- ./compiler/lua54.can:768 -pop("macroargs") -- ./compiler/lua54.can:769 -end -- ./compiler/lua54.can:769 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 -return r -- ./compiler/lua54.can:772 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 -else -- ./compiler/lua54.can:775 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 -end -- ./compiler/lua54.can:777 -else -- ./compiler/lua54.can:777 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 -end -- ./compiler/lua54.can:780 -end, -- ./compiler/lua54.can:780 -["SafeCall"] = function(t) -- ./compiler/lua54.can:784 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 -else -- ./compiler/lua54.can:786 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 -end -- ./compiler/lua54.can:788 -end, -- ./compiler/lua54.can:788 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 -if start == nil then start = 1 end -- ./compiler/lua54.can:793 -local r -- ./compiler/lua54.can:794 -if t[start] then -- ./compiler/lua54.can:795 -r = lua(t[start]) -- ./compiler/lua54.can:796 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 -end -- ./compiler/lua54.can:798 -else -- ./compiler/lua54.can:798 -r = "" -- ./compiler/lua54.can:801 -end -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:803 -end, -- ./compiler/lua54.can:803 -["Id"] = function(t) -- ./compiler/lua54.can:806 -local r = t[1] -- ./compiler/lua54.can:807 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 -r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 -local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 -if type(macro) == "function" then -- ./compiler/lua54.can:815 -r = macro() -- ./compiler/lua54.can:816 -else -- ./compiler/lua54.can:816 -r = lua(macro) -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 -end -- ./compiler/lua54.can:821 -return r -- ./compiler/lua54.can:823 -end, -- ./compiler/lua54.can:823 -["AttributeId"] = function(t) -- ./compiler/lua54.can:826 -if t[2] then -- ./compiler/lua54.can:827 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 -else -- ./compiler/lua54.can:828 -return t[1] -- ./compiler/lua54.can:830 -end -- ./compiler/lua54.can:830 -end, -- ./compiler/lua54.can:830 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 -if t["id"] then -- ./compiler/lua54.can:835 -return t["id"] -- ./compiler/lua54.can:836 -else -- ./compiler/lua54.can:836 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 -for j = 1, # t, 1 do -- ./compiler/lua54.can:840 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 -end -- ./compiler/lua54.can:841 -table["insert"](d, vars) -- ./compiler/lua54.can:843 -t["id"] = vars["id"] -- ./compiler/lua54.can:844 -return vars["id"] -- ./compiler/lua54.can:845 -end -- ./compiler/lua54.can:845 -end, -- ./compiler/lua54.can:845 -["Index"] = function(t) -- ./compiler/lua54.can:849 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 -else -- ./compiler/lua54.can:851 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 -end -- ./compiler/lua54.can:853 -end, -- ./compiler/lua54.can:853 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 -local l = {} -- ./compiler/lua54.can:859 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 -table["insert"](l, 1, t) -- ./compiler/lua54.can:861 -t = t[1] -- ./compiler/lua54.can:862 -end -- ./compiler/lua54.can:862 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 -for _, e in ipairs(l) do -- ./compiler/lua54.can:865 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 -else -- ./compiler/lua54.can:868 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 -return r -- ./compiler/lua54.can:874 -else -- ./compiler/lua54.can:874 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 -end -- ./compiler/lua54.can:876 -end, -- ./compiler/lua54.can:876 -["_opid"] = { -- ./compiler/lua54.can:881 -["add"] = "+", -- ./compiler/lua54.can:882 -["sub"] = "-", -- ./compiler/lua54.can:882 -["mul"] = "*", -- ./compiler/lua54.can:882 -["div"] = "/", -- ./compiler/lua54.can:882 -["idiv"] = "//", -- ./compiler/lua54.can:883 -["mod"] = "%", -- ./compiler/lua54.can:883 -["pow"] = "^", -- ./compiler/lua54.can:883 -["concat"] = "..", -- ./compiler/lua54.can:883 -["band"] = "&", -- ./compiler/lua54.can:884 -["bor"] = "|", -- ./compiler/lua54.can:884 -["bxor"] = "~", -- ./compiler/lua54.can:884 -["shl"] = "<<", -- ./compiler/lua54.can:884 -["shr"] = ">>", -- ./compiler/lua54.can:884 -["eq"] = "==", -- ./compiler/lua54.can:885 -["ne"] = "~=", -- ./compiler/lua54.can:885 -["lt"] = "<", -- ./compiler/lua54.can:885 -["gt"] = ">", -- ./compiler/lua54.can:885 -["le"] = "<=", -- ./compiler/lua54.can:885 -["ge"] = ">=", -- ./compiler/lua54.can:885 -["and"] = "and", -- ./compiler/lua54.can:886 -["or"] = "or", -- ./compiler/lua54.can:886 -["unm"] = "-", -- ./compiler/lua54.can:886 -["len"] = "#", -- ./compiler/lua54.can:886 -["bnot"] = "~", -- ./compiler/lua54.can:886 -["not"] = "not" -- ./compiler/lua54.can:886 -} -- ./compiler/lua54.can:886 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 -end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -4151,6 +5389,9 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua53.can:11 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:12 +end -- ./compiler/lua53.can:12 targetName = "Lua 5.2" -- ./compiler/lua52.can:1 APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 @@ -4204,14 +5445,17 @@ tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 end -- ./compiler/luajit.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 -return requireStr .. code -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -local lua54 = _() or lua54 -- ./compiler/lua54.can:902 -return lua54 -- ./compiler/lua53.can:18 -end -- ./compiler/lua53.can:18 -local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +return lua55 -- ./compiler/lua54.can:50 +end -- ./compiler/lua54.can:50 +local lua54 = _() or lua54 -- ./compiler/lua54.can:54 +return lua54 -- ./compiler/lua53.can:21 +end -- ./compiler/lua53.can:21 +local lua53 = _() or lua53 -- ./compiler/lua53.can:25 return lua53 -- ./compiler/lua52.can:35 end -- ./compiler/lua52.can:35 local lua52 = _() or lua52 -- ./compiler/lua52.can:39 @@ -4224,933 +5468,998 @@ local function _() -- ./compiler/luajit.can:48 local function _() -- ./compiler/luajit.can:50 local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 -local util = require("candran.util") -- ./compiler/lua54.can:1 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 -return function(code, ast, options, macros) -- ./compiler/lua54.can:7 -if macros == nil then macros = { -- ./compiler/lua54.can:7 -["functions"] = {}, -- ./compiler/lua54.can:7 -["variables"] = {} -- ./compiler/lua54.can:7 -} end -- ./compiler/lua54.can:7 -local lastInputPos = 1 -- ./compiler/lua54.can:9 -local prevLinePos = 1 -- ./compiler/lua54.can:10 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 -local lastLine = 1 -- ./compiler/lua54.can:12 -local indentLevel = 0 -- ./compiler/lua54.can:15 -local function newline() -- ./compiler/lua54.can:17 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 -if options["mapLines"] then -- ./compiler/lua54.can:19 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 +local function _() -- ./compiler/luajit.can:56 +local util = require("candran.util") -- ./compiler/lua55.can:1 +local targetName = "Lua 5.5" -- ./compiler/lua55.can:3 +local unpack = unpack or table["unpack"] -- ./compiler/lua55.can:5 +return function(code, ast, options, macros) -- ./compiler/lua55.can:7 +if macros == nil then macros = { -- ./compiler/lua55.can:7 +["functions"] = {}, -- ./compiler/lua55.can:7 +["variables"] = {} -- ./compiler/lua55.can:7 +} end -- ./compiler/lua55.can:7 +local lastInputPos = 1 -- ./compiler/lua55.can:9 +local prevLinePos = 1 -- ./compiler/lua55.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua55.can:11 +local lastLine = 1 -- ./compiler/lua55.can:12 +local indentLevel = 0 -- ./compiler/lua55.can:15 +local function newline() -- ./compiler/lua55.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua55.can:18 +if options["mapLines"] then -- ./compiler/lua55.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua55.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:21 -if source and line then -- ./compiler/lua54.can:23 -lastSource = source -- ./compiler/lua54.can:24 -lastLine = tonumber(line) -- ./compiler/lua54.can:25 -else -- ./compiler/lua54.can:25 +") -- ./compiler/lua55.can:21 +if source and line then -- ./compiler/lua55.can:23 +lastSource = source -- ./compiler/lua55.can:24 +lastLine = tonumber(line) -- ./compiler/lua55.can:25 +else -- ./compiler/lua55.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:27 -lastLine = lastLine + (1) -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -end -- ./compiler/lua54.can:28 -prevLinePos = lastInputPos -- ./compiler/lua54.can:32 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 -end -- ./compiler/lua54.can:34 -return r -- ./compiler/lua54.can:36 -end -- ./compiler/lua54.can:36 -local function indent() -- ./compiler/lua54.can:39 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 -return newline() -- ./compiler/lua54.can:41 +") do -- ./compiler/lua55.can:27 +lastLine = lastLine + (1) -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +end -- ./compiler/lua55.can:28 +prevLinePos = lastInputPos -- ./compiler/lua55.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua55.can:34 +end -- ./compiler/lua55.can:34 +return r -- ./compiler/lua55.can:36 +end -- ./compiler/lua55.can:36 +local function indent() -- ./compiler/lua55.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:40 +return newline() -- ./compiler/lua55.can:41 +end -- ./compiler/lua55.can:41 +local function unindent() -- ./compiler/lua55.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:45 +return newline() -- ./compiler/lua55.can:46 +end -- ./compiler/lua55.can:46 +local states = { -- ./compiler/lua55.can:51 +["push"] = {}, -- ./compiler/lua55.can:52 +["destructuring"] = {}, -- ./compiler/lua55.can:53 +["scope"] = {}, -- ./compiler/lua55.can:54 +["macroargs"] = {} -- ./compiler/lua55.can:55 +} -- ./compiler/lua55.can:55 +local function push(name, state) -- ./compiler/lua55.can:58 +table["insert"](states[name], state) -- ./compiler/lua55.can:59 +return "" -- ./compiler/lua55.can:60 +end -- ./compiler/lua55.can:60 +local function pop(name) -- ./compiler/lua55.can:63 +table["remove"](states[name]) -- ./compiler/lua55.can:64 +return "" -- ./compiler/lua55.can:65 +end -- ./compiler/lua55.can:65 +local function set(name, state) -- ./compiler/lua55.can:68 +states[name][# states[name]] = state -- ./compiler/lua55.can:69 +return "" -- ./compiler/lua55.can:70 +end -- ./compiler/lua55.can:70 +local function peek(name) -- ./compiler/lua55.can:73 +return states[name][# states[name]] -- ./compiler/lua55.can:74 +end -- ./compiler/lua55.can:74 +local function var(name) -- ./compiler/lua55.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua55.can:80 +end -- ./compiler/lua55.can:80 +local function tmp() -- ./compiler/lua55.can:84 +local scope = peek("scope") -- ./compiler/lua55.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua55.can:86 +table["insert"](scope, var) -- ./compiler/lua55.can:87 +return var -- ./compiler/lua55.can:88 +end -- ./compiler/lua55.can:88 +local nomacro = { -- ./compiler/lua55.can:92 +["variables"] = {}, -- ./compiler/lua55.can:92 +["functions"] = {} -- ./compiler/lua55.can:92 +} -- ./compiler/lua55.can:92 +local required = {} -- ./compiler/lua55.can:95 +local requireStr = "" -- ./compiler/lua55.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua55.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua55.can:99 +if not required[req] then -- ./compiler/lua55.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua55.can:101 +required[req] = true -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +end -- ./compiler/lua55.can:102 +local loop = { -- ./compiler/lua55.can:107 +"While", -- ./compiler/lua55.can:107 +"Repeat", -- ./compiler/lua55.can:107 +"Fornum", -- ./compiler/lua55.can:107 +"Forin", -- ./compiler/lua55.can:107 +"WhileExpr", -- ./compiler/lua55.can:107 +"RepeatExpr", -- ./compiler/lua55.can:107 +"FornumExpr", -- ./compiler/lua55.can:107 +"ForinExpr" -- ./compiler/lua55.can:107 +} -- ./compiler/lua55.can:107 +local func = { -- ./compiler/lua55.can:108 +"Function", -- ./compiler/lua55.can:108 +"TableCompr", -- ./compiler/lua55.can:108 +"DoExpr", -- ./compiler/lua55.can:108 +"WhileExpr", -- ./compiler/lua55.can:108 +"RepeatExpr", -- ./compiler/lua55.can:108 +"IfExpr", -- ./compiler/lua55.can:108 +"FornumExpr", -- ./compiler/lua55.can:108 +"ForinExpr" -- ./compiler/lua55.can:108 +} -- ./compiler/lua55.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua55.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:112 +local tagsCheck = {} -- ./compiler/lua55.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:114 +tagsCheck[tag] = true -- ./compiler/lua55.can:115 +end -- ./compiler/lua55.can:115 +local nofollowCheck = {} -- ./compiler/lua55.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:118 +nofollowCheck[tag] = true -- ./compiler/lua55.can:119 +end -- ./compiler/lua55.can:119 +for _, node in ipairs(list) do -- ./compiler/lua55.can:121 +if type(node) == "table" then -- ./compiler/lua55.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:123 +return node -- ./compiler/lua55.can:124 +end -- ./compiler/lua55.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua55.can:127 +if r then -- ./compiler/lua55.can:128 +return r -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +end -- ./compiler/lua55.can:128 +return nil -- ./compiler/lua55.can:132 +end -- ./compiler/lua55.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua55.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua55.can:137 +local tagsCheck = {} -- ./compiler/lua55.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:139 +tagsCheck[tag] = true -- ./compiler/lua55.can:140 +end -- ./compiler/lua55.can:140 +local nofollowCheck = {} -- ./compiler/lua55.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua55.can:143 +nofollowCheck[tag] = true -- ./compiler/lua55.can:144 +end -- ./compiler/lua55.can:144 +local found = {} -- ./compiler/lua55.can:146 +for _, node in ipairs(list) do -- ./compiler/lua55.can:147 +if type(node) == "table" then -- ./compiler/lua55.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua55.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua55.can:150 +table["insert"](found, n) -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +end -- ./compiler/lua55.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua55.can:154 +table["insert"](found, node) -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +end -- ./compiler/lua55.can:155 +return found -- ./compiler/lua55.can:159 +end -- ./compiler/lua55.can:159 +local function all(list, tags) -- ./compiler/lua55.can:163 +for _, node in ipairs(list) do -- ./compiler/lua55.can:164 +local ok = false -- ./compiler/lua55.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua55.can:166 +if node["tag"] == tag then -- ./compiler/lua55.can:167 +ok = true -- ./compiler/lua55.can:168 +break -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +end -- ./compiler/lua55.can:169 +if not ok then -- ./compiler/lua55.can:172 +return false -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +end -- ./compiler/lua55.can:173 +return true -- ./compiler/lua55.can:176 +end -- ./compiler/lua55.can:176 +local tags -- ./compiler/lua55.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua55.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua55.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua55.can:184 +end -- ./compiler/lua55.can:184 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua55.can:186 +end -- ./compiler/lua55.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua55.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua55.can:191 +end -- ./compiler/lua55.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua55.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua55.can:194 +end -- ./compiler/lua55.can:194 +local CONTINUE_START = function() -- ./compiler/lua55.can:196 +return "do" .. indent() -- ./compiler/lua55.can:197 +end -- ./compiler/lua55.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua55.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua55.can:200 +end -- ./compiler/lua55.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua55.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua55.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua55.can:202 +local vars = {} -- ./compiler/lua55.can:203 +local values = {} -- ./compiler/lua55.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua55.can:205 +for _, v in ipairs(list) do -- ./compiler/lua55.can:206 +local var, val -- ./compiler/lua55.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua55.can:208 +var = v -- ./compiler/lua55.can:209 +val = { -- ./compiler/lua55.can:210 +["tag"] = "Index", -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "Id", -- ./compiler/lua55.can:210 +list["id"] -- ./compiler/lua55.can:210 +}, -- ./compiler/lua55.can:210 +{ -- ./compiler/lua55.can:210 +["tag"] = "String", -- ./compiler/lua55.can:210 +v[1] -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +} -- ./compiler/lua55.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua55.can:211 +var = v[2] -- ./compiler/lua55.can:212 +val = { -- ./compiler/lua55.can:213 +["tag"] = "Index", -- ./compiler/lua55.can:213 +{ -- ./compiler/lua55.can:213 +["tag"] = "Id", -- ./compiler/lua55.can:213 +list["id"] -- ./compiler/lua55.can:213 +}, -- ./compiler/lua55.can:213 +v[1] -- ./compiler/lua55.can:213 +} -- ./compiler/lua55.can:213 +else -- ./compiler/lua55.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua55.can:215 +end -- ./compiler/lua55.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua55.can:217 +val = { -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["rightOp"], -- ./compiler/lua55.can:218 +var, -- ./compiler/lua55.can:218 +{ -- ./compiler/lua55.can:218 +["tag"] = "Op", -- ./compiler/lua55.can:218 +destructured["leftOp"], -- ./compiler/lua55.can:218 +val, -- ./compiler/lua55.can:218 +var -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +} -- ./compiler/lua55.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua55.can:219 +val = { -- ./compiler/lua55.can:220 +["tag"] = "Op", -- ./compiler/lua55.can:220 +destructured["rightOp"], -- ./compiler/lua55.can:220 +var, -- ./compiler/lua55.can:220 +val -- ./compiler/lua55.can:220 +} -- ./compiler/lua55.can:220 +elseif destructured["leftOp"] then -- ./compiler/lua55.can:221 +val = { -- ./compiler/lua55.can:222 +["tag"] = "Op", -- ./compiler/lua55.can:222 +destructured["leftOp"], -- ./compiler/lua55.can:222 +val, -- ./compiler/lua55.can:222 +var -- ./compiler/lua55.can:222 +} -- ./compiler/lua55.can:222 +end -- ./compiler/lua55.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua55.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +end -- ./compiler/lua55.can:225 +if # vars > 0 then -- ./compiler/lua55.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua55.can:229 +if newlineAfter then -- ./compiler/lua55.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua55.can:231 +else -- ./compiler/lua55.can:231 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua55.can:233 +end -- ./compiler/lua55.can:233 +else -- ./compiler/lua55.can:233 +return "" -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +end -- ./compiler/lua55.can:236 +tags = setmetatable({ -- ./compiler/lua55.can:241 +["Block"] = function(t) -- ./compiler/lua55.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua55.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua55.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua55.can:246 +hasPush = false -- ./compiler/lua55.can:247 +end -- ./compiler/lua55.can:247 +local r = push("scope", {}) -- ./compiler/lua55.can:249 +if hasPush then -- ./compiler/lua55.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:251 +end -- ./compiler/lua55.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua55.can:254 +end -- ./compiler/lua55.can:254 +if t[# t] then -- ./compiler/lua55.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua55.can:257 +end -- ./compiler/lua55.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua55.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua55.can:260 +end -- ./compiler/lua55.can:260 +return r .. pop("scope") -- ./compiler/lua55.can:262 +end, -- ./compiler/lua55.can:262 +["Do"] = function(t) -- ./compiler/lua55.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua55.can:269 +end, -- ./compiler/lua55.can:269 +["Set"] = function(t) -- ./compiler/lua55.can:272 +local expr = t[# t] -- ./compiler/lua55.can:274 +local vars, values = {}, {} -- ./compiler/lua55.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua55.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua55.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua55.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua55.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua55.can:280 +else -- ./compiler/lua55.can:280 +table["insert"](vars, n) -- ./compiler/lua55.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +end -- ./compiler/lua55.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua55.can:287 +local r = "" -- ./compiler/lua55.can:288 +if # vars > 0 then -- ./compiler/lua55.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua55.can:290 +end -- ./compiler/lua55.can:290 +if # destructuringVars > 0 then -- ./compiler/lua55.can:292 +local destructured = {} -- ./compiler/lua55.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:295 +end -- ./compiler/lua55.can:295 +return r -- ./compiler/lua55.can:297 +elseif # t == 4 then -- ./compiler/lua55.can:298 +if t[3] == "=" then -- ./compiler/lua55.can:299 +local r = "" -- ./compiler/lua55.can:300 +if # vars > 0 then -- ./compiler/lua55.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:302 +t[2], -- ./compiler/lua55.can:302 +vars[1], -- ./compiler/lua55.can:302 +{ -- ./compiler/lua55.can:302 +["tag"] = "Paren", -- ./compiler/lua55.can:302 +values[1] -- ./compiler/lua55.can:302 +} -- ./compiler/lua55.can:302 +}, "Op")) -- ./compiler/lua55.can:302 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua55.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:304 +t[2], -- ./compiler/lua55.can:304 +vars[i], -- ./compiler/lua55.can:304 +{ -- ./compiler/lua55.can:304 +["tag"] = "Paren", -- ./compiler/lua55.can:304 +values[i] -- ./compiler/lua55.can:304 +} -- ./compiler/lua55.can:304 +}, "Op")) -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +end -- ./compiler/lua55.can:304 +if # destructuringVars > 0 then -- ./compiler/lua55.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua55.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:310 +end -- ./compiler/lua55.can:310 +return r -- ./compiler/lua55.can:312 +else -- ./compiler/lua55.can:312 +local r = "" -- ./compiler/lua55.can:314 +if # vars > 0 then -- ./compiler/lua55.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:316 +t[3], -- ./compiler/lua55.can:316 +{ -- ./compiler/lua55.can:316 +["tag"] = "Paren", -- ./compiler/lua55.can:316 +values[1] -- ./compiler/lua55.can:316 +}, -- ./compiler/lua55.can:316 +vars[1] -- ./compiler/lua55.can:316 +}, "Op")) -- ./compiler/lua55.can:316 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua55.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:318 +t[3], -- ./compiler/lua55.can:318 +{ -- ./compiler/lua55.can:318 +["tag"] = "Paren", -- ./compiler/lua55.can:318 +values[i] -- ./compiler/lua55.can:318 +}, -- ./compiler/lua55.can:318 +vars[i] -- ./compiler/lua55.can:318 +}, "Op")) -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +end -- ./compiler/lua55.can:318 +if # destructuringVars > 0 then -- ./compiler/lua55.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua55.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:324 +end -- ./compiler/lua55.can:324 +return r -- ./compiler/lua55.can:326 +end -- ./compiler/lua55.can:326 +else -- ./compiler/lua55.can:326 +local r = "" -- ./compiler/lua55.can:329 +if # vars > 0 then -- ./compiler/lua55.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua55.can:331 +t[2], -- ./compiler/lua55.can:331 +vars[1], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Op", -- ./compiler/lua55.can:331 +t[4], -- ./compiler/lua55.can:331 +{ -- ./compiler/lua55.can:331 +["tag"] = "Paren", -- ./compiler/lua55.can:331 +values[1] -- ./compiler/lua55.can:331 +}, -- ./compiler/lua55.can:331 +vars[1] -- ./compiler/lua55.can:331 +} -- ./compiler/lua55.can:331 +}, "Op")) -- ./compiler/lua55.can:331 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua55.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua55.can:333 +t[2], -- ./compiler/lua55.can:333 +vars[i], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Op", -- ./compiler/lua55.can:333 +t[4], -- ./compiler/lua55.can:333 +{ -- ./compiler/lua55.can:333 +["tag"] = "Paren", -- ./compiler/lua55.can:333 +values[i] -- ./compiler/lua55.can:333 +}, -- ./compiler/lua55.can:333 +vars[i] -- ./compiler/lua55.can:333 +} -- ./compiler/lua55.can:333 +}, "Op")) -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +end -- ./compiler/lua55.can:333 +if # destructuringVars > 0 then -- ./compiler/lua55.can:336 +local destructured = { -- ./compiler/lua55.can:337 +["rightOp"] = t[2], -- ./compiler/lua55.can:337 +["leftOp"] = t[4] -- ./compiler/lua55.can:337 +} -- ./compiler/lua55.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua55.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua55.can:339 +end -- ./compiler/lua55.can:339 +return r -- ./compiler/lua55.can:341 +end -- ./compiler/lua55.can:341 +end, -- ./compiler/lua55.can:341 +["While"] = function(t) -- ./compiler/lua55.can:345 +local r = "" -- ./compiler/lua55.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua55.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:348 +if # lets > 0 then -- ./compiler/lua55.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +end -- ./compiler/lua55.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua55.can:355 +if # lets > 0 then -- ./compiler/lua55.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:357 +end -- ./compiler/lua55.can:357 +if hasContinue then -- ./compiler/lua55.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:360 +end -- ./compiler/lua55.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:362 +if hasContinue then -- ./compiler/lua55.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:364 +end -- ./compiler/lua55.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:366 +if # lets > 0 then -- ./compiler/lua55.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua55.can:369 +end -- ./compiler/lua55.can:369 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua55.can:371 +end -- ./compiler/lua55.can:371 +return r -- ./compiler/lua55.can:373 +end, -- ./compiler/lua55.can:373 +["Repeat"] = function(t) -- ./compiler/lua55.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua55.can:377 +local r = "repeat" .. indent() -- ./compiler/lua55.can:378 +if hasContinue then -- ./compiler/lua55.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:380 +end -- ./compiler/lua55.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua55.can:382 +if hasContinue then -- ./compiler/lua55.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:384 +end -- ./compiler/lua55.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua55.can:386 +return r -- ./compiler/lua55.can:387 +end, -- ./compiler/lua55.can:387 +["If"] = function(t) -- ./compiler/lua55.can:390 +local r = "" -- ./compiler/lua55.can:391 +local toClose = 0 -- ./compiler/lua55.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua55.can:393 +if # lets > 0 then -- ./compiler/lua55.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua55.can:395 +toClose = toClose + (1) -- ./compiler/lua55.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +end -- ./compiler/lua55.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua55.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua55.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua55.can:403 +if # lets > 0 then -- ./compiler/lua55.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua55.can:405 +toClose = toClose + (1) -- ./compiler/lua55.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua55.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua55.can:408 +end -- ./compiler/lua55.can:408 +else -- ./compiler/lua55.can:408 +r = r .. ("else") -- ./compiler/lua55.can:411 +end -- ./compiler/lua55.can:411 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua55.can:413 +end -- ./compiler/lua55.can:413 +if # t % 2 == 1 then -- ./compiler/lua55.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua55.can:416 +end -- ./compiler/lua55.can:416 +r = r .. ("end") -- ./compiler/lua55.can:418 +for i = 1, toClose do -- ./compiler/lua55.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua55.can:420 +end -- ./compiler/lua55.can:420 +return r -- ./compiler/lua55.can:422 +end, -- ./compiler/lua55.can:422 +["Fornum"] = function(t) -- ./compiler/lua55.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua55.can:426 +if # t == 5 then -- ./compiler/lua55.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua55.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua55.can:429 +if hasContinue then -- ./compiler/lua55.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:431 +end -- ./compiler/lua55.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua55.can:433 +if hasContinue then -- ./compiler/lua55.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:435 +end -- ./compiler/lua55.can:435 +return r .. unindent() .. "end" -- ./compiler/lua55.can:437 +else -- ./compiler/lua55.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua55.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua55.can:440 +if hasContinue then -- ./compiler/lua55.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:442 +end -- ./compiler/lua55.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua55.can:444 +if hasContinue then -- ./compiler/lua55.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:446 +end -- ./compiler/lua55.can:446 +return r .. unindent() .. "end" -- ./compiler/lua55.can:448 +end -- ./compiler/lua55.can:448 +end, -- ./compiler/lua55.can:448 +["Forin"] = function(t) -- ./compiler/lua55.can:452 +local destructured = {} -- ./compiler/lua55.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua55.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua55.can:455 +if hasContinue then -- ./compiler/lua55.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua55.can:457 +end -- ./compiler/lua55.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua55.can:459 +if hasContinue then -- ./compiler/lua55.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua55.can:461 +end -- ./compiler/lua55.can:461 +return r .. unindent() .. "end" -- ./compiler/lua55.can:463 +end, -- ./compiler/lua55.can:463 +["Local"] = function(t) -- ./compiler/lua55.can:466 +local destructured = {} -- ./compiler/lua55.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:468 +if t[2][1] then -- ./compiler/lua55.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:470 +end -- ./compiler/lua55.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:472 +end, -- ./compiler/lua55.can:472 +["Global"] = function(t) -- ./compiler/lua55.can:475 +local destructured = {} -- ./compiler/lua55.can:476 +local r = "global " .. push("destructuring", destructured) .. lua(t[1]) .. pop("destructuring") -- ./compiler/lua55.can:477 +if t[2][1] then -- ./compiler/lua55.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:479 +end -- ./compiler/lua55.can:479 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:481 +end, -- ./compiler/lua55.can:481 +["Let"] = function(t) -- ./compiler/lua55.can:484 +local destructured = {} -- ./compiler/lua55.can:485 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua55.can:486 +local r = "local " .. nameList -- ./compiler/lua55.can:487 +if t[2][1] then -- ./compiler/lua55.can:488 +if all(t[2], { -- ./compiler/lua55.can:489 +"Nil", -- ./compiler/lua55.can:489 +"Dots", -- ./compiler/lua55.can:489 +"Boolean", -- ./compiler/lua55.can:489 +"Number", -- ./compiler/lua55.can:489 +"String" -- ./compiler/lua55.can:489 +}) then -- ./compiler/lua55.can:489 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:490 +else -- ./compiler/lua55.can:490 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +end -- ./compiler/lua55.can:492 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua55.can:495 +end, -- ./compiler/lua55.can:495 +["Localrec"] = function(t) -- ./compiler/lua55.can:498 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:499 +end, -- ./compiler/lua55.can:499 +["Globalrec"] = function(t) -- ./compiler/lua55.can:502 +return "global function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua55.can:503 +end, -- ./compiler/lua55.can:503 +["GlobalAll"] = function(t) -- ./compiler/lua55.can:506 +if # t == 1 then -- ./compiler/lua55.can:507 +return "global <" .. t[1] .. "> *" -- ./compiler/lua55.can:508 +else -- ./compiler/lua55.can:508 +return "global *" -- ./compiler/lua55.can:510 +end -- ./compiler/lua55.can:510 +end, -- ./compiler/lua55.can:510 +["Goto"] = function(t) -- ./compiler/lua55.can:514 +return "goto " .. lua(t, "Id") -- ./compiler/lua55.can:515 +end, -- ./compiler/lua55.can:515 +["Label"] = function(t) -- ./compiler/lua55.can:518 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua55.can:519 +end, -- ./compiler/lua55.can:519 +["Return"] = function(t) -- ./compiler/lua55.can:522 +local push = peek("push") -- ./compiler/lua55.can:523 +if push then -- ./compiler/lua55.can:524 +local r = "" -- ./compiler/lua55.can:525 +for _, val in ipairs(t) do -- ./compiler/lua55.can:526 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua55.can:527 +end -- ./compiler/lua55.can:527 +return r .. "return " .. UNPACK(push) -- ./compiler/lua55.can:529 +else -- ./compiler/lua55.can:529 +return "return " .. lua(t, "_lhs") -- ./compiler/lua55.can:531 +end -- ./compiler/lua55.can:531 +end, -- ./compiler/lua55.can:531 +["Push"] = function(t) -- ./compiler/lua55.can:535 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua55.can:536 +r = "" -- ./compiler/lua55.can:537 +for i = 1, # t - 1, 1 do -- ./compiler/lua55.can:538 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua55.can:539 +end -- ./compiler/lua55.can:539 +if t[# t] then -- ./compiler/lua55.can:541 +if t[# t]["tag"] == "Call" then -- ./compiler/lua55.can:542 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua55.can:543 +else -- ./compiler/lua55.can:543 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +end -- ./compiler/lua55.can:545 +return r -- ./compiler/lua55.can:548 +end, -- ./compiler/lua55.can:548 +["Break"] = function() -- ./compiler/lua55.can:551 +return "break" -- ./compiler/lua55.can:552 +end, -- ./compiler/lua55.can:552 +["Continue"] = function() -- ./compiler/lua55.can:555 +return "goto " .. var("continue") -- ./compiler/lua55.can:556 +end, -- ./compiler/lua55.can:556 +["Nil"] = function() -- ./compiler/lua55.can:563 +return "nil" -- ./compiler/lua55.can:564 +end, -- ./compiler/lua55.can:564 +["Dots"] = function() -- ./compiler/lua55.can:567 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:568 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua55.can:569 +nomacro["variables"]["..."] = true -- ./compiler/lua55.can:570 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua55.can:571 +nomacro["variables"]["..."] = nil -- ./compiler/lua55.can:572 +return r -- ./compiler/lua55.can:573 +else -- ./compiler/lua55.can:573 +return "..." -- ./compiler/lua55.can:575 +end -- ./compiler/lua55.can:575 +end, -- ./compiler/lua55.can:575 +["Boolean"] = function(t) -- ./compiler/lua55.can:579 +return tostring(t[1]) -- ./compiler/lua55.can:580 +end, -- ./compiler/lua55.can:580 +["Number"] = function(t) -- ./compiler/lua55.can:583 +return tostring(t[1]) -- ./compiler/lua55.can:584 +end, -- ./compiler/lua55.can:584 +["String"] = function(t) -- ./compiler/lua55.can:587 +return ("%q"):format(t[1]) -- ./compiler/lua55.can:588 +end, -- ./compiler/lua55.can:588 +["_functionParameter"] = { -- ./compiler/lua55.can:591 +["ParPair"] = function(t, decl) -- ./compiler/lua55.can:592 +local id = lua(t[1]) -- ./compiler/lua55.can:593 +indentLevel = indentLevel + (1) -- ./compiler/lua55.can:594 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[2]) .. " end") -- ./compiler/lua55.can:595 +indentLevel = indentLevel - (1) -- ./compiler/lua55.can:596 +return id -- ./compiler/lua55.can:597 +end, -- ./compiler/lua55.can:597 +["ParDots"] = function(t, decl) -- ./compiler/lua55.can:599 +if # t == 1 then -- ./compiler/lua55.can:600 +return "..." .. lua(t[1]) -- ./compiler/lua55.can:601 +else -- ./compiler/lua55.can:601 +return "..." -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +end -- ./compiler/lua55.can:603 +}, -- ./compiler/lua55.can:603 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua55.can:607 +local r = "(" -- ./compiler/lua55.can:608 +local decl = {} -- ./compiler/lua55.can:609 +local pars = {} -- ./compiler/lua55.can:610 +for i = 1, # t[1], 1 do -- ./compiler/lua55.can:611 +if tags["_functionParameter"][t[1][i]["tag"]] then -- ./compiler/lua55.can:612 +table["insert"](pars, tags["_functionParameter"][t[1][i]["tag"]](t[1][i], decl)) -- ./compiler/lua55.can:613 +else -- ./compiler/lua55.can:613 +table["insert"](pars, lua(t[1][i])) -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +end -- ./compiler/lua55.can:615 +r = r .. (table["concat"](pars, ", ") .. ")" .. indent()) -- ./compiler/lua55.can:618 +for _, d in ipairs(decl) do -- ./compiler/lua55.can:619 +r = r .. (d .. newline()) -- ./compiler/lua55.can:620 +end -- ./compiler/lua55.can:620 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua55.can:622 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua55.can:623 +end -- ./compiler/lua55.can:623 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua55.can:625 +if hasPush then -- ./compiler/lua55.can:626 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:627 +else -- ./compiler/lua55.can:627 +push("push", false) -- ./compiler/lua55.can:629 +end -- ./compiler/lua55.can:629 +r = r .. (lua(t[2])) -- ./compiler/lua55.can:631 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua55.can:632 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:633 +end -- ./compiler/lua55.can:633 +pop("push") -- ./compiler/lua55.can:635 +return r .. unindent() .. "end" -- ./compiler/lua55.can:636 +end, -- ./compiler/lua55.can:636 +["Function"] = function(t) -- ./compiler/lua55.can:638 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua55.can:639 +end, -- ./compiler/lua55.can:639 +["Pair"] = function(t) -- ./compiler/lua55.can:642 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua55.can:643 +end, -- ./compiler/lua55.can:643 +["Table"] = function(t) -- ./compiler/lua55.can:645 +if # t == 0 then -- ./compiler/lua55.can:646 +return "{}" -- ./compiler/lua55.can:647 +elseif # t == 1 then -- ./compiler/lua55.can:648 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua55.can:649 +else -- ./compiler/lua55.can:649 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua55.can:651 +end -- ./compiler/lua55.can:651 +end, -- ./compiler/lua55.can:651 +["TableCompr"] = function(t) -- ./compiler/lua55.can:655 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua55.can:656 +end, -- ./compiler/lua55.can:656 +["Op"] = function(t) -- ./compiler/lua55.can:659 +local r -- ./compiler/lua55.can:660 +if # t == 2 then -- ./compiler/lua55.can:661 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:662 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua55.can:663 +else -- ./compiler/lua55.can:663 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua55.can:665 +end -- ./compiler/lua55.can:665 +else -- ./compiler/lua55.can:665 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua55.can:668 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua55.can:669 +else -- ./compiler/lua55.can:669 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +end -- ./compiler/lua55.can:671 +return r -- ./compiler/lua55.can:674 +end, -- ./compiler/lua55.can:674 +["Paren"] = function(t) -- ./compiler/lua55.can:677 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua55.can:678 +end, -- ./compiler/lua55.can:678 +["MethodStub"] = function(t) -- ./compiler/lua55.can:681 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:687 +end, -- ./compiler/lua55.can:687 +["SafeMethodStub"] = function(t) -- ./compiler/lua55.can:690 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua55.can:697 +end, -- ./compiler/lua55.can:697 +["LetExpr"] = function(t) -- ./compiler/lua55.can:704 +return lua(t[1][1]) -- ./compiler/lua55.can:705 +end, -- ./compiler/lua55.can:705 +["_statexpr"] = function(t, stat) -- ./compiler/lua55.can:709 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua55.can:710 +local r = "(function()" .. indent() -- ./compiler/lua55.can:711 +if hasPush then -- ./compiler/lua55.can:712 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua55.can:713 +else -- ./compiler/lua55.can:713 +push("push", false) -- ./compiler/lua55.can:715 +end -- ./compiler/lua55.can:715 +r = r .. (lua(t, stat)) -- ./compiler/lua55.can:717 +if hasPush then -- ./compiler/lua55.can:718 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua55.can:719 +end -- ./compiler/lua55.can:719 +pop("push") -- ./compiler/lua55.can:721 +r = r .. (unindent() .. "end)()") -- ./compiler/lua55.can:722 +return r -- ./compiler/lua55.can:723 +end, -- ./compiler/lua55.can:723 +["DoExpr"] = function(t) -- ./compiler/lua55.can:726 +if t[# t]["tag"] == "Push" then -- ./compiler/lua55.can:727 +t[# t]["tag"] = "Return" -- ./compiler/lua55.can:728 +end -- ./compiler/lua55.can:728 +return lua(t, "_statexpr", "Do") -- ./compiler/lua55.can:730 +end, -- ./compiler/lua55.can:730 +["WhileExpr"] = function(t) -- ./compiler/lua55.can:733 +return lua(t, "_statexpr", "While") -- ./compiler/lua55.can:734 +end, -- ./compiler/lua55.can:734 +["RepeatExpr"] = function(t) -- ./compiler/lua55.can:737 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua55.can:738 +end, -- ./compiler/lua55.can:738 +["IfExpr"] = function(t) -- ./compiler/lua55.can:741 +for i = 2, # t do -- ./compiler/lua55.can:742 +local block = t[i] -- ./compiler/lua55.can:743 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua55.can:744 +block[# block]["tag"] = "Return" -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +end -- ./compiler/lua55.can:745 +return lua(t, "_statexpr", "If") -- ./compiler/lua55.can:748 +end, -- ./compiler/lua55.can:748 +["FornumExpr"] = function(t) -- ./compiler/lua55.can:751 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua55.can:752 +end, -- ./compiler/lua55.can:752 +["ForinExpr"] = function(t) -- ./compiler/lua55.can:755 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua55.can:756 +end, -- ./compiler/lua55.can:756 +["Call"] = function(t) -- ./compiler/lua55.can:762 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:763 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:764 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua55.can:765 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua55.can:766 +local replacement = macro["replacement"] -- ./compiler/lua55.can:767 +local r -- ./compiler/lua55.can:768 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua55.can:769 +if type(replacement) == "function" then -- ./compiler/lua55.can:770 +local args = {} -- ./compiler/lua55.can:771 +for i = 2, # t do -- ./compiler/lua55.can:772 +table["insert"](args, lua(t[i])) -- ./compiler/lua55.can:773 +end -- ./compiler/lua55.can:773 +r = replacement(unpack(args)) -- ./compiler/lua55.can:775 +else -- ./compiler/lua55.can:775 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua55.can:777 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua55.can:778 +if arg["tag"] == "Dots" then -- ./compiler/lua55.can:779 +macroargs["..."] = (function() -- ./compiler/lua55.can:780 +local self = {} -- ./compiler/lua55.can:780 +for j = i + 1, # t do -- ./compiler/lua55.can:780 +self[#self+1] = t[j] -- ./compiler/lua55.can:780 +end -- ./compiler/lua55.can:780 +return self -- ./compiler/lua55.can:780 +end)() -- ./compiler/lua55.can:780 +elseif arg["tag"] == "Id" then -- ./compiler/lua55.can:781 +if t[i + 1] == nil then -- ./compiler/lua55.can:782 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua55.can:783 +end -- ./compiler/lua55.can:783 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua55.can:785 +else -- ./compiler/lua55.can:785 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +end -- ./compiler/lua55.can:787 +push("macroargs", macroargs) -- ./compiler/lua55.can:790 +r = lua(replacement) -- ./compiler/lua55.can:791 +pop("macroargs") -- ./compiler/lua55.can:792 +end -- ./compiler/lua55.can:792 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua55.can:794 +return r -- ./compiler/lua55.can:795 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua55.can:796 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua55.can:797 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:798 +else -- ./compiler/lua55.can:798 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:800 +end -- ./compiler/lua55.can:800 +else -- ./compiler/lua55.can:800 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua55.can:803 +end -- ./compiler/lua55.can:803 +end, -- ./compiler/lua55.can:803 +["SafeCall"] = function(t) -- ./compiler/lua55.can:807 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:808 +return lua(t, "SafeIndex") -- ./compiler/lua55.can:809 +else -- ./compiler/lua55.can:809 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua55.can:811 +end -- ./compiler/lua55.can:811 +end, -- ./compiler/lua55.can:811 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua55.can:816 +if start == nil then start = 1 end -- ./compiler/lua55.can:816 +local r -- ./compiler/lua55.can:817 +if t[start] then -- ./compiler/lua55.can:818 +r = lua(t[start]) -- ./compiler/lua55.can:819 +for i = start + 1, # t, 1 do -- ./compiler/lua55.can:820 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua55.can:821 +end -- ./compiler/lua55.can:821 +else -- ./compiler/lua55.can:821 +r = "" -- ./compiler/lua55.can:824 +end -- ./compiler/lua55.can:824 +return r -- ./compiler/lua55.can:826 +end, -- ./compiler/lua55.can:826 +["Id"] = function(t) -- ./compiler/lua55.can:829 +local r = t[1] -- ./compiler/lua55.can:830 +local macroargs = peek("macroargs") -- ./compiler/lua55.can:831 +if not nomacro["variables"][t[1]] then -- ./compiler/lua55.can:832 +nomacro["variables"][t[1]] = true -- ./compiler/lua55.can:833 +if macroargs and macroargs[t[1]] then -- ./compiler/lua55.can:834 +r = lua(macroargs[t[1]]) -- ./compiler/lua55.can:835 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua55.can:836 +local macro = macros["variables"][t[1]] -- ./compiler/lua55.can:837 +if type(macro) == "function" then -- ./compiler/lua55.can:838 +r = macro() -- ./compiler/lua55.can:839 +else -- ./compiler/lua55.can:839 +r = lua(macro) -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +end -- ./compiler/lua55.can:841 +nomacro["variables"][t[1]] = nil -- ./compiler/lua55.can:844 +end -- ./compiler/lua55.can:844 +return r -- ./compiler/lua55.can:846 +end, -- ./compiler/lua55.can:846 +["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua55.can:849 +return "<" .. t[1] .. "> " .. lua(t, "_lhs", 2) -- ./compiler/lua55.can:850 +end, -- ./compiler/lua55.can:850 +["AttributeNameList"] = function(t) -- ./compiler/lua55.can:853 +return lua(t, "_lhs") -- ./compiler/lua55.can:854 +end, -- ./compiler/lua55.can:854 +["NameList"] = function(t) -- ./compiler/lua55.can:857 +return lua(t, "_lhs") -- ./compiler/lua55.can:858 +end, -- ./compiler/lua55.can:858 +["AttributeId"] = function(t) -- ./compiler/lua55.can:861 +if t[2] then -- ./compiler/lua55.can:862 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua55.can:863 +else -- ./compiler/lua55.can:863 +return t[1] -- ./compiler/lua55.can:865 +end -- ./compiler/lua55.can:865 +end, -- ./compiler/lua55.can:865 +["DestructuringId"] = function(t) -- ./compiler/lua55.can:869 +if t["id"] then -- ./compiler/lua55.can:870 +return t["id"] -- ./compiler/lua55.can:871 +else -- ./compiler/lua55.can:871 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment") -- ./compiler/lua55.can:873 +local vars = { ["id"] = tmp() } -- ./compiler/lua55.can:874 +for j = 1, # t, 1 do -- ./compiler/lua55.can:875 +table["insert"](vars, t[j]) -- ./compiler/lua55.can:876 +end -- ./compiler/lua55.can:876 +table["insert"](d, vars) -- ./compiler/lua55.can:878 +t["id"] = vars["id"] -- ./compiler/lua55.can:879 +return vars["id"] -- ./compiler/lua55.can:880 +end -- ./compiler/lua55.can:880 +end, -- ./compiler/lua55.can:880 +["Index"] = function(t) -- ./compiler/lua55.can:884 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua55.can:885 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:886 +else -- ./compiler/lua55.can:886 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua55.can:888 +end -- ./compiler/lua55.can:888 +end, -- ./compiler/lua55.can:888 +["SafeIndex"] = function(t) -- ./compiler/lua55.can:892 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua55.can:893 +local l = {} -- ./compiler/lua55.can:894 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua55.can:895 +table["insert"](l, 1, t) -- ./compiler/lua55.can:896 +t = t[1] -- ./compiler/lua55.can:897 +end -- ./compiler/lua55.can:897 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua55.can:899 +for _, e in ipairs(l) do -- ./compiler/lua55.can:900 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua55.can:901 +if e["tag"] == "SafeIndex" then -- ./compiler/lua55.can:902 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua55.can:903 +else -- ./compiler/lua55.can:903 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +end -- ./compiler/lua55.can:905 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua55.can:908 +return r -- ./compiler/lua55.can:909 +else -- ./compiler/lua55.can:909 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua55.can:911 +end -- ./compiler/lua55.can:911 +end, -- ./compiler/lua55.can:911 +["_opid"] = { -- ./compiler/lua55.can:916 +["add"] = "+", -- ./compiler/lua55.can:917 +["sub"] = "-", -- ./compiler/lua55.can:917 +["mul"] = "*", -- ./compiler/lua55.can:917 +["div"] = "/", -- ./compiler/lua55.can:917 +["idiv"] = "//", -- ./compiler/lua55.can:918 +["mod"] = "%", -- ./compiler/lua55.can:918 +["pow"] = "^", -- ./compiler/lua55.can:918 +["concat"] = "..", -- ./compiler/lua55.can:918 +["band"] = "&", -- ./compiler/lua55.can:919 +["bor"] = "|", -- ./compiler/lua55.can:919 +["bxor"] = "~", -- ./compiler/lua55.can:919 +["shl"] = "<<", -- ./compiler/lua55.can:919 +["shr"] = ">>", -- ./compiler/lua55.can:919 +["eq"] = "==", -- ./compiler/lua55.can:920 +["ne"] = "~=", -- ./compiler/lua55.can:920 +["lt"] = "<", -- ./compiler/lua55.can:920 +["gt"] = ">", -- ./compiler/lua55.can:920 +["le"] = "<=", -- ./compiler/lua55.can:920 +["ge"] = ">=", -- ./compiler/lua55.can:920 +["and"] = "and", -- ./compiler/lua55.can:921 +["or"] = "or", -- ./compiler/lua55.can:921 +["unm"] = "-", -- ./compiler/lua55.can:921 +["len"] = "#", -- ./compiler/lua55.can:921 +["bnot"] = "~", -- ./compiler/lua55.can:921 +["not"] = "not" -- ./compiler/lua55.can:921 +} -- ./compiler/lua55.can:921 +}, { ["__index"] = function(self, key) -- ./compiler/lua55.can:924 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua55.can:925 +end }) -- ./compiler/lua55.can:925 +targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +tags["Global"] = function(t) -- ./compiler/lua54.can:4 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:5 +end -- ./compiler/lua54.can:5 +tags["Globalrec"] = function(t) -- ./compiler/lua54.can:7 +error("target " .. targetName .. " does not support global variable declaration") -- ./compiler/lua54.can:8 +end -- ./compiler/lua54.can:8 +tags["GlobalAll"] = function(t) -- ./compiler/lua54.can:10 +if # t == 1 then -- ./compiler/lua54.can:11 +error("target " .. targetName .. " does not support collective global variable declaration") -- ./compiler/lua54.can:12 +else -- ./compiler/lua54.can:12 +return "" -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +end -- ./compiler/lua54.can:14 +tags["_functionParameter"]["ParDots"] = function(t, decl) -- ./compiler/lua54.can:19 +if # t == 1 then -- ./compiler/lua54.can:20 +local id = lua(t[1]) -- ./compiler/lua54.can:21 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:22 +table["insert"](decl, "local " .. id .. " = { ... }") -- ./compiler/lua54.can:23 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +return "..." -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua54.can:31 +local ids = {} -- ./compiler/lua54.can:32 +for i = 2, # t, 1 do -- ./compiler/lua54.can:33 +if t[i][2] then -- ./compiler/lua54.can:34 +error("target " .. targetName .. " does not support combining prefixed and suffixed attributes in variable declaration") -- ./compiler/lua54.can:35 +else -- ./compiler/lua54.can:35 +t[i][2] = t[1] -- ./compiler/lua54.can:37 +table["insert"](ids, lua(t[i])) -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +end -- ./compiler/lua54.can:38 +return table["concat"](ids, ", ") -- ./compiler/lua54.can:41 end -- ./compiler/lua54.can:41 -local function unindent() -- ./compiler/lua54.can:44 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 -return newline() -- ./compiler/lua54.can:46 -end -- ./compiler/lua54.can:46 -local states = { -- ./compiler/lua54.can:51 -["push"] = {}, -- ./compiler/lua54.can:52 -["destructuring"] = {}, -- ./compiler/lua54.can:53 -["scope"] = {}, -- ./compiler/lua54.can:54 -["macroargs"] = {} -- ./compiler/lua54.can:55 -} -- ./compiler/lua54.can:55 -local function push(name, state) -- ./compiler/lua54.can:58 -table["insert"](states[name], state) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function pop(name) -- ./compiler/lua54.can:63 -table["remove"](states[name]) -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function set(name, state) -- ./compiler/lua54.can:68 -states[name][# states[name]] = state -- ./compiler/lua54.can:69 -return "" -- ./compiler/lua54.can:70 -end -- ./compiler/lua54.can:70 -local function peek(name) -- ./compiler/lua54.can:73 -return states[name][# states[name]] -- ./compiler/lua54.can:74 -end -- ./compiler/lua54.can:74 -local function var(name) -- ./compiler/lua54.can:79 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 -end -- ./compiler/lua54.can:80 -local function tmp() -- ./compiler/lua54.can:84 -local scope = peek("scope") -- ./compiler/lua54.can:85 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 -table["insert"](scope, var) -- ./compiler/lua54.can:87 -return var -- ./compiler/lua54.can:88 -end -- ./compiler/lua54.can:88 -local nomacro = { -- ./compiler/lua54.can:92 -["variables"] = {}, -- ./compiler/lua54.can:92 -["functions"] = {} -- ./compiler/lua54.can:92 -} -- ./compiler/lua54.can:92 -local required = {} -- ./compiler/lua54.can:95 -local requireStr = "" -- ./compiler/lua54.can:96 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 -if not required[req] then -- ./compiler/lua54.can:100 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 -required[req] = true -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -end -- ./compiler/lua54.can:102 -local loop = { -- ./compiler/lua54.can:107 -"While", -- ./compiler/lua54.can:107 -"Repeat", -- ./compiler/lua54.can:107 -"Fornum", -- ./compiler/lua54.can:107 -"Forin", -- ./compiler/lua54.can:107 -"WhileExpr", -- ./compiler/lua54.can:107 -"RepeatExpr", -- ./compiler/lua54.can:107 -"FornumExpr", -- ./compiler/lua54.can:107 -"ForinExpr" -- ./compiler/lua54.can:107 -} -- ./compiler/lua54.can:107 -local func = { -- ./compiler/lua54.can:108 -"Function", -- ./compiler/lua54.can:108 -"TableCompr", -- ./compiler/lua54.can:108 -"DoExpr", -- ./compiler/lua54.can:108 -"WhileExpr", -- ./compiler/lua54.can:108 -"RepeatExpr", -- ./compiler/lua54.can:108 -"IfExpr", -- ./compiler/lua54.can:108 -"FornumExpr", -- ./compiler/lua54.can:108 -"ForinExpr" -- ./compiler/lua54.can:108 -} -- ./compiler/lua54.can:108 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 -local tagsCheck = {} -- ./compiler/lua54.can:113 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 -tagsCheck[tag] = true -- ./compiler/lua54.can:115 -end -- ./compiler/lua54.can:115 -local nofollowCheck = {} -- ./compiler/lua54.can:117 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 -nofollowCheck[tag] = true -- ./compiler/lua54.can:119 -end -- ./compiler/lua54.can:119 -for _, node in ipairs(list) do -- ./compiler/lua54.can:121 -if type(node) == "table" then -- ./compiler/lua54.can:122 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 -return node -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 -if r then -- ./compiler/lua54.can:128 -return r -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -end -- ./compiler/lua54.can:128 -return nil -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 -local tagsCheck = {} -- ./compiler/lua54.can:138 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 -tagsCheck[tag] = true -- ./compiler/lua54.can:140 -end -- ./compiler/lua54.can:140 -local nofollowCheck = {} -- ./compiler/lua54.can:142 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 -nofollowCheck[tag] = true -- ./compiler/lua54.can:144 -end -- ./compiler/lua54.can:144 -local found = {} -- ./compiler/lua54.can:146 -for _, node in ipairs(list) do -- ./compiler/lua54.can:147 -if type(node) == "table" then -- ./compiler/lua54.can:148 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 -table["insert"](found, n) -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 -table["insert"](found, node) -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -end -- ./compiler/lua54.can:155 -return found -- ./compiler/lua54.can:159 -end -- ./compiler/lua54.can:159 -local function all(list, tags) -- ./compiler/lua54.can:163 -for _, node in ipairs(list) do -- ./compiler/lua54.can:164 -local ok = false -- ./compiler/lua54.can:165 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 -if node["tag"] == tag then -- ./compiler/lua54.can:167 -ok = true -- ./compiler/lua54.can:168 -break -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -end -- ./compiler/lua54.can:169 -if not ok then -- ./compiler/lua54.can:172 -return false -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -end -- ./compiler/lua54.can:173 -return true -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -local tags -- ./compiler/lua54.can:180 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 -end -- ./compiler/lua54.can:184 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 -end -- ./compiler/lua54.can:191 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 -end -- ./compiler/lua54.can:194 -local CONTINUE_START = function() -- ./compiler/lua54.can:196 -return "do" .. indent() -- ./compiler/lua54.can:197 -end -- ./compiler/lua54.can:197 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 -end -- ./compiler/lua54.can:200 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 -local vars = {} -- ./compiler/lua54.can:203 -local values = {} -- ./compiler/lua54.can:204 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 -for _, v in ipairs(list) do -- ./compiler/lua54.can:206 -local var, val -- ./compiler/lua54.can:207 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 -var = v -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Index", -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Id", -- ./compiler/lua54.can:210 -list["id"] -- ./compiler/lua54.can:210 -}, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "String", -- ./compiler/lua54.can:210 -v[1] -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 -var = v[2] -- ./compiler/lua54.can:212 -val = { -- ./compiler/lua54.can:213 -["tag"] = "Index", -- ./compiler/lua54.can:213 -{ -- ./compiler/lua54.can:213 -["tag"] = "Id", -- ./compiler/lua54.can:213 -list["id"] -- ./compiler/lua54.can:213 -}, -- ./compiler/lua54.can:213 -v[1] -- ./compiler/lua54.can:213 -} -- ./compiler/lua54.can:213 -else -- ./compiler/lua54.can:213 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 -end -- ./compiler/lua54.can:215 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 -val = { -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["rightOp"], -- ./compiler/lua54.can:218 -var, -- ./compiler/lua54.can:218 -{ -- ./compiler/lua54.can:218 -["tag"] = "Op", -- ./compiler/lua54.can:218 -destructured["leftOp"], -- ./compiler/lua54.can:218 -val, -- ./compiler/lua54.can:218 -var -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -} -- ./compiler/lua54.can:218 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 -val = { -- ./compiler/lua54.can:220 -["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["rightOp"], -- ./compiler/lua54.can:220 -var, -- ./compiler/lua54.can:220 -val -- ./compiler/lua54.can:220 -} -- ./compiler/lua54.can:220 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 -val = { -- ./compiler/lua54.can:222 -["tag"] = "Op", -- ./compiler/lua54.can:222 -destructured["leftOp"], -- ./compiler/lua54.can:222 -val, -- ./compiler/lua54.can:222 -var -- ./compiler/lua54.can:222 -} -- ./compiler/lua54.can:222 -end -- ./compiler/lua54.can:222 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -if # vars > 0 then -- ./compiler/lua54.can:228 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 -if newlineAfter then -- ./compiler/lua54.can:230 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 -else -- ./compiler/lua54.can:231 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 -end -- ./compiler/lua54.can:233 -else -- ./compiler/lua54.can:233 -return "" -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -end -- ./compiler/lua54.can:236 -tags = setmetatable({ -- ./compiler/lua54.can:241 -["Block"] = function(t) -- ./compiler/lua54.can:243 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 -hasPush = false -- ./compiler/lua54.can:247 -end -- ./compiler/lua54.can:247 -local r = push("scope", {}) -- ./compiler/lua54.can:249 -if hasPush then -- ./compiler/lua54.can:250 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 -end -- ./compiler/lua54.can:251 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 -end -- ./compiler/lua54.can:254 -if t[# t] then -- ./compiler/lua54.can:256 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 -end -- ./compiler/lua54.can:257 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 -end -- ./compiler/lua54.can:260 -return r .. pop("scope") -- ./compiler/lua54.can:262 -end, -- ./compiler/lua54.can:262 -["Do"] = function(t) -- ./compiler/lua54.can:268 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 -end, -- ./compiler/lua54.can:269 -["Set"] = function(t) -- ./compiler/lua54.can:272 -local expr = t[# t] -- ./compiler/lua54.can:274 -local vars, values = {}, {} -- ./compiler/lua54.can:275 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 -else -- ./compiler/lua54.can:280 -table["insert"](vars, n) -- ./compiler/lua54.can:282 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -end -- ./compiler/lua54.can:283 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 -local r = "" -- ./compiler/lua54.can:288 -if # vars > 0 then -- ./compiler/lua54.can:289 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 -end -- ./compiler/lua54.can:290 -if # destructuringVars > 0 then -- ./compiler/lua54.can:292 -local destructured = {} -- ./compiler/lua54.can:293 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 -end -- ./compiler/lua54.can:295 -return r -- ./compiler/lua54.can:297 -elseif # t == 4 then -- ./compiler/lua54.can:298 -if t[3] == "=" then -- ./compiler/lua54.can:299 -local r = "" -- ./compiler/lua54.can:300 -if # vars > 0 then -- ./compiler/lua54.can:301 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 -t[2], -- ./compiler/lua54.can:302 -vars[1], -- ./compiler/lua54.can:302 -{ -- ./compiler/lua54.can:302 -["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[1] -- ./compiler/lua54.can:302 -} -- ./compiler/lua54.can:302 -}, "Op")) -- ./compiler/lua54.can:302 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 -t[2], -- ./compiler/lua54.can:304 -vars[i], -- ./compiler/lua54.can:304 -{ -- ./compiler/lua54.can:304 -["tag"] = "Paren", -- ./compiler/lua54.can:304 -values[i] -- ./compiler/lua54.can:304 -} -- ./compiler/lua54.can:304 -}, "Op")) -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -end -- ./compiler/lua54.can:304 -if # destructuringVars > 0 then -- ./compiler/lua54.can:307 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -return r -- ./compiler/lua54.can:312 -else -- ./compiler/lua54.can:312 -local r = "" -- ./compiler/lua54.can:314 -if # vars > 0 then -- ./compiler/lua54.can:315 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 -t[3], -- ./compiler/lua54.can:316 -{ -- ./compiler/lua54.can:316 -["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[1] -- ./compiler/lua54.can:316 -}, -- ./compiler/lua54.can:316 -vars[1] -- ./compiler/lua54.can:316 -}, "Op")) -- ./compiler/lua54.can:316 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 -t[3], -- ./compiler/lua54.can:318 -{ -- ./compiler/lua54.can:318 -["tag"] = "Paren", -- ./compiler/lua54.can:318 -values[i] -- ./compiler/lua54.can:318 -}, -- ./compiler/lua54.can:318 -vars[i] -- ./compiler/lua54.can:318 -}, "Op")) -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -if # destructuringVars > 0 then -- ./compiler/lua54.can:321 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 -end -- ./compiler/lua54.can:324 -return r -- ./compiler/lua54.can:326 -end -- ./compiler/lua54.can:326 -else -- ./compiler/lua54.can:326 -local r = "" -- ./compiler/lua54.can:329 -if # vars > 0 then -- ./compiler/lua54.can:330 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 -t[2], -- ./compiler/lua54.can:331 -vars[1], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Op", -- ./compiler/lua54.can:331 -t[4], -- ./compiler/lua54.can:331 -{ -- ./compiler/lua54.can:331 -["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[1] -- ./compiler/lua54.can:331 -}, -- ./compiler/lua54.can:331 -vars[1] -- ./compiler/lua54.can:331 -} -- ./compiler/lua54.can:331 -}, "Op")) -- ./compiler/lua54.can:331 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 -t[2], -- ./compiler/lua54.can:333 -vars[i], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Op", -- ./compiler/lua54.can:333 -t[4], -- ./compiler/lua54.can:333 -{ -- ./compiler/lua54.can:333 -["tag"] = "Paren", -- ./compiler/lua54.can:333 -values[i] -- ./compiler/lua54.can:333 -}, -- ./compiler/lua54.can:333 -vars[i] -- ./compiler/lua54.can:333 -} -- ./compiler/lua54.can:333 -}, "Op")) -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -if # destructuringVars > 0 then -- ./compiler/lua54.can:336 -local destructured = { -- ./compiler/lua54.can:337 -["rightOp"] = t[2], -- ./compiler/lua54.can:337 -["leftOp"] = t[4] -- ./compiler/lua54.can:337 -} -- ./compiler/lua54.can:337 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 -end -- ./compiler/lua54.can:339 -return r -- ./compiler/lua54.can:341 -end -- ./compiler/lua54.can:341 -end, -- ./compiler/lua54.can:341 -["While"] = function(t) -- ./compiler/lua54.can:345 -local r = "" -- ./compiler/lua54.can:346 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 -if # lets > 0 then -- ./compiler/lua54.can:349 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 -if # lets > 0 then -- ./compiler/lua54.can:356 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 -end -- ./compiler/lua54.can:357 -if hasContinue then -- ./compiler/lua54.can:359 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 -end -- ./compiler/lua54.can:360 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 -if hasContinue then -- ./compiler/lua54.can:363 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 -end -- ./compiler/lua54.can:364 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 -if # lets > 0 then -- ./compiler/lua54.can:367 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 -end -- ./compiler/lua54.can:369 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 -end -- ./compiler/lua54.can:371 -return r -- ./compiler/lua54.can:373 -end, -- ./compiler/lua54.can:373 -["Repeat"] = function(t) -- ./compiler/lua54.can:376 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 -local r = "repeat" .. indent() -- ./compiler/lua54.can:378 -if hasContinue then -- ./compiler/lua54.can:379 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 -end -- ./compiler/lua54.can:380 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 -if hasContinue then -- ./compiler/lua54.can:383 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 -end -- ./compiler/lua54.can:384 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 -return r -- ./compiler/lua54.can:387 -end, -- ./compiler/lua54.can:387 -["If"] = function(t) -- ./compiler/lua54.can:390 -local r = "" -- ./compiler/lua54.can:391 -local toClose = 0 -- ./compiler/lua54.can:392 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 -if # lets > 0 then -- ./compiler/lua54.can:394 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 -toClose = toClose + (1) -- ./compiler/lua54.can:396 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -end -- ./compiler/lua54.can:398 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 -if # lets > 0 then -- ./compiler/lua54.can:404 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 -toClose = toClose + (1) -- ./compiler/lua54.can:406 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -else -- ./compiler/lua54.can:408 -r = r .. ("else") -- ./compiler/lua54.can:411 -end -- ./compiler/lua54.can:411 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 -end -- ./compiler/lua54.can:413 -if # t % 2 == 1 then -- ./compiler/lua54.can:415 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 -end -- ./compiler/lua54.can:416 -r = r .. ("end") -- ./compiler/lua54.can:418 -for i = 1, toClose do -- ./compiler/lua54.can:419 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 -end -- ./compiler/lua54.can:420 -return r -- ./compiler/lua54.can:422 -end, -- ./compiler/lua54.can:422 -["Fornum"] = function(t) -- ./compiler/lua54.can:425 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 -if # t == 5 then -- ./compiler/lua54.can:427 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 -if hasContinue then -- ./compiler/lua54.can:430 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 -end -- ./compiler/lua54.can:431 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 -if hasContinue then -- ./compiler/lua54.can:434 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 -end -- ./compiler/lua54.can:435 -return r .. unindent() .. "end" -- ./compiler/lua54.can:437 -else -- ./compiler/lua54.can:437 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 -if hasContinue then -- ./compiler/lua54.can:441 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 -end -- ./compiler/lua54.can:442 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 -if hasContinue then -- ./compiler/lua54.can:445 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 -end -- ./compiler/lua54.can:446 -return r .. unindent() .. "end" -- ./compiler/lua54.can:448 -end -- ./compiler/lua54.can:448 -end, -- ./compiler/lua54.can:448 -["Forin"] = function(t) -- ./compiler/lua54.can:452 -local destructured = {} -- ./compiler/lua54.can:453 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 -if hasContinue then -- ./compiler/lua54.can:456 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 -end -- ./compiler/lua54.can:457 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 -if hasContinue then -- ./compiler/lua54.can:460 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 -end -- ./compiler/lua54.can:461 -return r .. unindent() .. "end" -- ./compiler/lua54.can:463 -end, -- ./compiler/lua54.can:463 -["Local"] = function(t) -- ./compiler/lua54.can:466 -local destructured = {} -- ./compiler/lua54.can:467 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 -if t[2][1] then -- ./compiler/lua54.can:469 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 -end -- ./compiler/lua54.can:470 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 -end, -- ./compiler/lua54.can:472 -["Let"] = function(t) -- ./compiler/lua54.can:475 -local destructured = {} -- ./compiler/lua54.can:476 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 -local r = "local " .. nameList -- ./compiler/lua54.can:478 -if t[2][1] then -- ./compiler/lua54.can:479 -if all(t[2], { -- ./compiler/lua54.can:480 -"Nil", -- ./compiler/lua54.can:480 -"Dots", -- ./compiler/lua54.can:480 -"Boolean", -- ./compiler/lua54.can:480 -"Number", -- ./compiler/lua54.can:480 -"String" -- ./compiler/lua54.can:480 -}) then -- ./compiler/lua54.can:480 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -else -- ./compiler/lua54.can:481 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -end -- ./compiler/lua54.can:483 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Localrec"] = function(t) -- ./compiler/lua54.can:489 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Goto"] = function(t) -- ./compiler/lua54.can:493 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 -end, -- ./compiler/lua54.can:494 -["Label"] = function(t) -- ./compiler/lua54.can:497 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 -end, -- ./compiler/lua54.can:498 -["Return"] = function(t) -- ./compiler/lua54.can:501 -local push = peek("push") -- ./compiler/lua54.can:502 -if push then -- ./compiler/lua54.can:503 -local r = "" -- ./compiler/lua54.can:504 -for _, val in ipairs(t) do -- ./compiler/lua54.can:505 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 -end -- ./compiler/lua54.can:506 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 -else -- ./compiler/lua54.can:508 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -end, -- ./compiler/lua54.can:510 -["Push"] = function(t) -- ./compiler/lua54.can:514 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 -r = "" -- ./compiler/lua54.can:516 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 -end -- ./compiler/lua54.can:518 -if t[# t] then -- ./compiler/lua54.can:520 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 -else -- ./compiler/lua54.can:522 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -end -- ./compiler/lua54.can:524 -return r -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Break"] = function() -- ./compiler/lua54.can:530 -return "break" -- ./compiler/lua54.can:531 -end, -- ./compiler/lua54.can:531 -["Continue"] = function() -- ./compiler/lua54.can:534 -return "goto " .. var("continue") -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Nil"] = function() -- ./compiler/lua54.can:542 -return "nil" -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Dots"] = function() -- ./compiler/lua54.can:546 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 -return r -- ./compiler/lua54.can:552 -else -- ./compiler/lua54.can:552 -return "..." -- ./compiler/lua54.can:554 -end -- ./compiler/lua54.can:554 -end, -- ./compiler/lua54.can:554 -["Boolean"] = function(t) -- ./compiler/lua54.can:558 -return tostring(t[1]) -- ./compiler/lua54.can:559 -end, -- ./compiler/lua54.can:559 -["Number"] = function(t) -- ./compiler/lua54.can:562 -return tostring(t[1]) -- ./compiler/lua54.can:563 -end, -- ./compiler/lua54.can:563 -["String"] = function(t) -- ./compiler/lua54.can:566 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 -end, -- ./compiler/lua54.can:567 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 -local r = "(" -- ./compiler/lua54.can:571 -local decl = {} -- ./compiler/lua54.can:572 -if t[1][1] then -- ./compiler/lua54.can:573 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 -r = r .. (id) -- ./compiler/lua54.can:579 -else -- ./compiler/lua54.can:579 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 -r = r .. (", " .. id) -- ./compiler/lua54.can:589 -else -- ./compiler/lua54.can:589 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -end -- ./compiler/lua54.can:591 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 -r = r .. (d .. newline()) -- ./compiler/lua54.can:597 -end -- ./compiler/lua54.can:597 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 -end -- ./compiler/lua54.can:600 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 -if hasPush then -- ./compiler/lua54.can:603 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 -else -- ./compiler/lua54.can:604 -push("push", false) -- ./compiler/lua54.can:606 -end -- ./compiler/lua54.can:606 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 -end -- ./compiler/lua54.can:610 -pop("push") -- ./compiler/lua54.can:612 -return r .. unindent() .. "end" -- ./compiler/lua54.can:613 -end, -- ./compiler/lua54.can:613 -["Function"] = function(t) -- ./compiler/lua54.can:615 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 -end, -- ./compiler/lua54.can:616 -["Pair"] = function(t) -- ./compiler/lua54.can:619 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 -end, -- ./compiler/lua54.can:620 -["Table"] = function(t) -- ./compiler/lua54.can:622 -if # t == 0 then -- ./compiler/lua54.can:623 -return "{}" -- ./compiler/lua54.can:624 -elseif # t == 1 then -- ./compiler/lua54.can:625 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 -end -- ./compiler/lua54.can:628 -end, -- ./compiler/lua54.can:628 -["TableCompr"] = function(t) -- ./compiler/lua54.can:632 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 -end, -- ./compiler/lua54.can:633 -["Op"] = function(t) -- ./compiler/lua54.can:636 -local r -- ./compiler/lua54.can:637 -if # t == 2 then -- ./compiler/lua54.can:638 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 -else -- ./compiler/lua54.can:640 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 -end -- ./compiler/lua54.can:642 -else -- ./compiler/lua54.can:642 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 -else -- ./compiler/lua54.can:646 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -end -- ./compiler/lua54.can:648 -return r -- ./compiler/lua54.can:651 -end, -- ./compiler/lua54.can:651 -["Paren"] = function(t) -- ./compiler/lua54.can:654 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 -end, -- ./compiler/lua54.can:655 -["MethodStub"] = function(t) -- ./compiler/lua54.can:658 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 -end, -- ./compiler/lua54.can:664 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 -end, -- ./compiler/lua54.can:674 -["LetExpr"] = function(t) -- ./compiler/lua54.can:681 -return lua(t[1][1]) -- ./compiler/lua54.can:682 -end, -- ./compiler/lua54.can:682 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 -local r = "(function()" .. indent() -- ./compiler/lua54.can:688 -if hasPush then -- ./compiler/lua54.can:689 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 -else -- ./compiler/lua54.can:690 -push("push", false) -- ./compiler/lua54.can:692 -end -- ./compiler/lua54.can:692 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 -if hasPush then -- ./compiler/lua54.can:695 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 -end -- ./compiler/lua54.can:696 -pop("push") -- ./compiler/lua54.can:698 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 -return r -- ./compiler/lua54.can:700 -end, -- ./compiler/lua54.can:700 -["DoExpr"] = function(t) -- ./compiler/lua54.can:703 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 -end -- ./compiler/lua54.can:705 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 -end, -- ./compiler/lua54.can:707 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 -end, -- ./compiler/lua54.can:711 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 -end, -- ./compiler/lua54.can:715 -["IfExpr"] = function(t) -- ./compiler/lua54.can:718 -for i = 2, # t do -- ./compiler/lua54.can:719 -local block = t[i] -- ./compiler/lua54.can:720 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -end -- ./compiler/lua54.can:722 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 -end, -- ./compiler/lua54.can:725 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 -end, -- ./compiler/lua54.can:729 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["Call"] = function(t) -- ./compiler/lua54.can:739 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 -local replacement = macro["replacement"] -- ./compiler/lua54.can:744 -local r -- ./compiler/lua54.can:745 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 -if type(replacement) == "function" then -- ./compiler/lua54.can:747 -local args = {} -- ./compiler/lua54.can:748 -for i = 2, # t do -- ./compiler/lua54.can:749 -table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 -end -- ./compiler/lua54.can:750 -r = replacement(unpack(args)) -- ./compiler/lua54.can:752 -else -- ./compiler/lua54.can:752 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 -macroargs["..."] = (function() -- ./compiler/lua54.can:757 -local self = {} -- ./compiler/lua54.can:757 -for j = i + 1, # t do -- ./compiler/lua54.can:757 -self[#self+1] = t[j] -- ./compiler/lua54.can:757 -end -- ./compiler/lua54.can:757 -return self -- ./compiler/lua54.can:757 -end)() -- ./compiler/lua54.can:757 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 -if t[i + 1] == nil then -- ./compiler/lua54.can:759 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 -end -- ./compiler/lua54.can:760 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 -else -- ./compiler/lua54.can:762 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -end -- ./compiler/lua54.can:764 -push("macroargs", macroargs) -- ./compiler/lua54.can:767 -r = lua(replacement) -- ./compiler/lua54.can:768 -pop("macroargs") -- ./compiler/lua54.can:769 -end -- ./compiler/lua54.can:769 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 -return r -- ./compiler/lua54.can:772 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 -else -- ./compiler/lua54.can:775 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 -end -- ./compiler/lua54.can:777 -else -- ./compiler/lua54.can:777 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 -end -- ./compiler/lua54.can:780 -end, -- ./compiler/lua54.can:780 -["SafeCall"] = function(t) -- ./compiler/lua54.can:784 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 -else -- ./compiler/lua54.can:786 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 -end -- ./compiler/lua54.can:788 -end, -- ./compiler/lua54.can:788 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 -if start == nil then start = 1 end -- ./compiler/lua54.can:793 -local r -- ./compiler/lua54.can:794 -if t[start] then -- ./compiler/lua54.can:795 -r = lua(t[start]) -- ./compiler/lua54.can:796 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 -end -- ./compiler/lua54.can:798 -else -- ./compiler/lua54.can:798 -r = "" -- ./compiler/lua54.can:801 -end -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:803 -end, -- ./compiler/lua54.can:803 -["Id"] = function(t) -- ./compiler/lua54.can:806 -local r = t[1] -- ./compiler/lua54.can:807 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 -r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 -local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 -if type(macro) == "function" then -- ./compiler/lua54.can:815 -r = macro() -- ./compiler/lua54.can:816 -else -- ./compiler/lua54.can:816 -r = lua(macro) -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -end -- ./compiler/lua54.can:818 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 -end -- ./compiler/lua54.can:821 -return r -- ./compiler/lua54.can:823 -end, -- ./compiler/lua54.can:823 -["AttributeId"] = function(t) -- ./compiler/lua54.can:826 -if t[2] then -- ./compiler/lua54.can:827 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 -else -- ./compiler/lua54.can:828 -return t[1] -- ./compiler/lua54.can:830 -end -- ./compiler/lua54.can:830 -end, -- ./compiler/lua54.can:830 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 -if t["id"] then -- ./compiler/lua54.can:835 -return t["id"] -- ./compiler/lua54.can:836 -else -- ./compiler/lua54.can:836 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 -for j = 1, # t, 1 do -- ./compiler/lua54.can:840 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 -end -- ./compiler/lua54.can:841 -table["insert"](d, vars) -- ./compiler/lua54.can:843 -t["id"] = vars["id"] -- ./compiler/lua54.can:844 -return vars["id"] -- ./compiler/lua54.can:845 -end -- ./compiler/lua54.can:845 -end, -- ./compiler/lua54.can:845 -["Index"] = function(t) -- ./compiler/lua54.can:849 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 -else -- ./compiler/lua54.can:851 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 -end -- ./compiler/lua54.can:853 -end, -- ./compiler/lua54.can:853 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 -local l = {} -- ./compiler/lua54.can:859 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 -table["insert"](l, 1, t) -- ./compiler/lua54.can:861 -t = t[1] -- ./compiler/lua54.can:862 -end -- ./compiler/lua54.can:862 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 -for _, e in ipairs(l) do -- ./compiler/lua54.can:865 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 -else -- ./compiler/lua54.can:868 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -end -- ./compiler/lua54.can:870 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 -return r -- ./compiler/lua54.can:874 -else -- ./compiler/lua54.can:874 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 -end -- ./compiler/lua54.can:876 -end, -- ./compiler/lua54.can:876 -["_opid"] = { -- ./compiler/lua54.can:881 -["add"] = "+", -- ./compiler/lua54.can:882 -["sub"] = "-", -- ./compiler/lua54.can:882 -["mul"] = "*", -- ./compiler/lua54.can:882 -["div"] = "/", -- ./compiler/lua54.can:882 -["idiv"] = "//", -- ./compiler/lua54.can:883 -["mod"] = "%", -- ./compiler/lua54.can:883 -["pow"] = "^", -- ./compiler/lua54.can:883 -["concat"] = "..", -- ./compiler/lua54.can:883 -["band"] = "&", -- ./compiler/lua54.can:884 -["bor"] = "|", -- ./compiler/lua54.can:884 -["bxor"] = "~", -- ./compiler/lua54.can:884 -["shl"] = "<<", -- ./compiler/lua54.can:884 -["shr"] = ">>", -- ./compiler/lua54.can:884 -["eq"] = "==", -- ./compiler/lua54.can:885 -["ne"] = "~=", -- ./compiler/lua54.can:885 -["lt"] = "<", -- ./compiler/lua54.can:885 -["gt"] = ">", -- ./compiler/lua54.can:885 -["le"] = "<=", -- ./compiler/lua54.can:885 -["ge"] = ">=", -- ./compiler/lua54.can:885 -["and"] = "and", -- ./compiler/lua54.can:886 -["or"] = "or", -- ./compiler/lua54.can:886 -["unm"] = "-", -- ./compiler/lua54.can:886 -["len"] = "#", -- ./compiler/lua54.can:886 -["bnot"] = "~", -- ./compiler/lua54.can:886 -["not"] = "not" -- ./compiler/lua54.can:886 -} -- ./compiler/lua54.can:886 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 -end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -5159,6 +6468,9 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 +tags["PrefixedAttributeNameList"] = function(t) -- ./compiler/lua53.can:11 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:12 +end -- ./compiler/lua53.can:12 targetName = "Lua 5.2" -- ./compiler/lua52.can:1 APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 @@ -5237,14 +6549,17 @@ end -- ./compiler/lua51.can:26 tags["Label"] = function() -- ./compiler/lua51.can:28 error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 end -- ./compiler/lua51.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 -return requireStr .. code -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -end -- ./compiler/lua54.can:897 -local lua54 = _() or lua54 -- ./compiler/lua54.can:902 -return lua54 -- ./compiler/lua53.can:18 -end -- ./compiler/lua53.can:18 -local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +local code = lua(ast) .. newline() -- ./compiler/lua55.can:931 +return requireStr .. code -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +end -- ./compiler/lua55.can:932 +local lua55 = _() or lua55 -- ./compiler/lua55.can:937 +return lua55 -- ./compiler/lua54.can:50 +end -- ./compiler/lua54.can:50 +local lua54 = _() or lua54 -- ./compiler/lua54.can:54 +return lua54 -- ./compiler/lua53.can:21 +end -- ./compiler/lua53.can:21 +local lua53 = _() or lua53 -- ./compiler/lua53.can:25 return lua53 -- ./compiler/lua52.can:35 end -- ./compiler/lua52.can:35 local lua52 = _() or lua52 -- ./compiler/lua52.can:39 @@ -5325,511 +6640,513 @@ end -- ./candran/can-parser/scope.lua:74 local scope = _() or scope -- ./candran/can-parser/scope.lua:78 package["loaded"]["candran.can-parser.scope"] = scope or true -- ./candran/can-parser/scope.lua:79 local function _() -- ./candran/can-parser/scope.lua:82 -local scope = require("candran.can-parser.scope") -- ./candran/can-parser/validator.lua:4 -local lineno = scope["lineno"] -- ./candran/can-parser/validator.lua:6 -local new_scope, end_scope = scope["new_scope"], scope["end_scope"] -- ./candran/can-parser/validator.lua:7 -local new_function, end_function = scope["new_function"], scope["end_function"] -- ./candran/can-parser/validator.lua:8 -local begin_loop, end_loop = scope["begin_loop"], scope["end_loop"] -- ./candran/can-parser/validator.lua:9 -local insideloop = scope["insideloop"] -- ./candran/can-parser/validator.lua:10 -local function syntaxerror(errorinfo, pos, msg) -- ./candran/can-parser/validator.lua:13 -local l, c = lineno(errorinfo["subject"], pos) -- ./candran/can-parser/validator.lua:14 -local error_msg = "%s:%d:%d: syntax error, %s" -- ./candran/can-parser/validator.lua:15 -return string["format"](error_msg, errorinfo["filename"], l, c, msg) -- ./candran/can-parser/validator.lua:16 -end -- ./candran/can-parser/validator.lua:16 -local function exist_label(env, scope, stm) -- ./candran/can-parser/validator.lua:19 -local l = stm[1] -- ./candran/can-parser/validator.lua:20 -for s = scope, 0, - 1 do -- ./candran/can-parser/validator.lua:21 -if env[s]["label"][l] then -- ./candran/can-parser/validator.lua:22 -return true -- ./candran/can-parser/validator.lua:22 -end -- ./candran/can-parser/validator.lua:22 -end -- ./candran/can-parser/validator.lua:22 -return false -- ./candran/can-parser/validator.lua:24 -end -- ./candran/can-parser/validator.lua:24 -local function set_label(env, label, pos) -- ./candran/can-parser/validator.lua:27 -local scope = env["scope"] -- ./candran/can-parser/validator.lua:28 -local l = env[scope]["label"][label] -- ./candran/can-parser/validator.lua:29 -if not l then -- ./candran/can-parser/validator.lua:30 -env[scope]["label"][label] = { -- ./candran/can-parser/validator.lua:31 -["name"] = label, -- ./candran/can-parser/validator.lua:31 -["pos"] = pos -- ./candran/can-parser/validator.lua:31 -} -- ./candran/can-parser/validator.lua:31 -return true -- ./candran/can-parser/validator.lua:32 -else -- ./candran/can-parser/validator.lua:32 -local msg = "label '%s' already defined at line %d" -- ./candran/can-parser/validator.lua:34 -local line = lineno(env["errorinfo"]["subject"], l["pos"]) -- ./candran/can-parser/validator.lua:35 -msg = string["format"](msg, label, line) -- ./candran/can-parser/validator.lua:36 -return nil, syntaxerror(env["errorinfo"], pos, msg) -- ./candran/can-parser/validator.lua:37 -end -- ./candran/can-parser/validator.lua:37 -end -- ./candran/can-parser/validator.lua:37 -local function set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:41 -local scope = env["scope"] -- ./candran/can-parser/validator.lua:42 -table["insert"](env[scope]["goto"], stm) -- ./candran/can-parser/validator.lua:43 -return true -- ./candran/can-parser/validator.lua:44 -end -- ./candran/can-parser/validator.lua:44 -local function verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:47 -for s = env["maxscope"], 0, - 1 do -- ./candran/can-parser/validator.lua:48 -for k, v in ipairs(env[s]["goto"]) do -- ./candran/can-parser/validator.lua:49 -if not exist_label(env, s, v) then -- ./candran/can-parser/validator.lua:50 -local msg = "no visible label '%s' for " -- ./candran/can-parser/validator.lua:51 -msg = string["format"](msg, v[1]) -- ./candran/can-parser/validator.lua:52 -return nil, syntaxerror(env["errorinfo"], v["pos"], msg) -- ./candran/can-parser/validator.lua:53 -end -- ./candran/can-parser/validator.lua:53 -end -- ./candran/can-parser/validator.lua:53 -end -- ./candran/can-parser/validator.lua:53 -return true -- ./candran/can-parser/validator.lua:57 +local scope = require("candran.can-parser.scope") -- ./candran/can-parser/validator.lua:8 +local lineno = scope["lineno"] -- ./candran/can-parser/validator.lua:10 +local new_scope, end_scope = scope["new_scope"], scope["end_scope"] -- ./candran/can-parser/validator.lua:11 +local new_function, end_function = scope["new_function"], scope["end_function"] -- ./candran/can-parser/validator.lua:12 +local begin_loop, end_loop = scope["begin_loop"], scope["end_loop"] -- ./candran/can-parser/validator.lua:13 +local insideloop = scope["insideloop"] -- ./candran/can-parser/validator.lua:14 +local function syntaxerror(errorinfo, pos, msg) -- ./candran/can-parser/validator.lua:17 +local l, c = lineno(errorinfo["subject"], pos) -- ./candran/can-parser/validator.lua:18 +local error_msg = "%s:%d:%d: syntax error, %s" -- ./candran/can-parser/validator.lua:19 +return string["format"](error_msg, errorinfo["filename"], l, c, msg) -- ./candran/can-parser/validator.lua:20 +end -- ./candran/can-parser/validator.lua:20 +local function exist_label(env, scope, stm) -- ./candran/can-parser/validator.lua:23 +local l = stm[1] -- ./candran/can-parser/validator.lua:24 +for s = scope, 0, - 1 do -- ./candran/can-parser/validator.lua:25 +if env[s]["label"][l] then -- ./candran/can-parser/validator.lua:26 +return true -- ./candran/can-parser/validator.lua:26 +end -- ./candran/can-parser/validator.lua:26 +end -- ./candran/can-parser/validator.lua:26 +return false -- ./candran/can-parser/validator.lua:28 +end -- ./candran/can-parser/validator.lua:28 +local function set_label(env, label, pos) -- ./candran/can-parser/validator.lua:31 +local scope = env["scope"] -- ./candran/can-parser/validator.lua:32 +local l = env[scope]["label"][label] -- ./candran/can-parser/validator.lua:33 +if not l then -- ./candran/can-parser/validator.lua:34 +env[scope]["label"][label] = { -- ./candran/can-parser/validator.lua:35 +["name"] = label, -- ./candran/can-parser/validator.lua:35 +["pos"] = pos -- ./candran/can-parser/validator.lua:35 +} -- ./candran/can-parser/validator.lua:35 +return true -- ./candran/can-parser/validator.lua:36 +else -- ./candran/can-parser/validator.lua:36 +local msg = "label '%s' already defined at line %d" -- ./candran/can-parser/validator.lua:38 +local line = lineno(env["errorinfo"]["subject"], l["pos"]) -- ./candran/can-parser/validator.lua:39 +msg = string["format"](msg, label, line) -- ./candran/can-parser/validator.lua:40 +return nil, syntaxerror(env["errorinfo"], pos, msg) -- ./candran/can-parser/validator.lua:41 +end -- ./candran/can-parser/validator.lua:41 +end -- ./candran/can-parser/validator.lua:41 +local function set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:45 +local scope = env["scope"] -- ./candran/can-parser/validator.lua:46 +table["insert"](env[scope]["goto"], stm) -- ./candran/can-parser/validator.lua:47 +return true -- ./candran/can-parser/validator.lua:48 +end -- ./candran/can-parser/validator.lua:48 +local function verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:51 +for s = env["maxscope"], 0, - 1 do -- ./candran/can-parser/validator.lua:52 +for k, v in ipairs(env[s]["goto"]) do -- ./candran/can-parser/validator.lua:53 +if not exist_label(env, s, v) then -- ./candran/can-parser/validator.lua:54 +local msg = "no visible label '%s' for " -- ./candran/can-parser/validator.lua:55 +msg = string["format"](msg, v[1]) -- ./candran/can-parser/validator.lua:56 +return nil, syntaxerror(env["errorinfo"], v["pos"], msg) -- ./candran/can-parser/validator.lua:57 end -- ./candran/can-parser/validator.lua:57 -local function set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:60 -env["function"][env["fscope"]]["is_vararg"] = is_vararg -- ./candran/can-parser/validator.lua:61 +end -- ./candran/can-parser/validator.lua:57 +end -- ./candran/can-parser/validator.lua:57 +return true -- ./candran/can-parser/validator.lua:61 end -- ./candran/can-parser/validator.lua:61 -local traverse_stm, traverse_exp, traverse_var -- ./candran/can-parser/validator.lua:64 -local traverse_block, traverse_explist, traverse_varlist, traverse_parlist -- ./candran/can-parser/validator.lua:65 -traverse_parlist = function(env, parlist) -- ./candran/can-parser/validator.lua:67 -local len = # parlist -- ./candran/can-parser/validator.lua:68 -local is_vararg = false -- ./candran/can-parser/validator.lua:69 -if len > 0 and parlist[len]["tag"] == "Dots" then -- ./candran/can-parser/validator.lua:70 -is_vararg = true -- ./candran/can-parser/validator.lua:71 -end -- ./candran/can-parser/validator.lua:71 -set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:73 -return true -- ./candran/can-parser/validator.lua:74 -end -- ./candran/can-parser/validator.lua:74 -local function traverse_function(env, exp) -- ./candran/can-parser/validator.lua:77 -new_function(env) -- ./candran/can-parser/validator.lua:78 -new_scope(env) -- ./candran/can-parser/validator.lua:79 -local status, msg = traverse_parlist(env, exp[1]) -- ./candran/can-parser/validator.lua:80 -if not status then -- ./candran/can-parser/validator.lua:81 -return status, msg -- ./candran/can-parser/validator.lua:81 -end -- ./candran/can-parser/validator.lua:81 -status, msg = traverse_block(env, exp[2]) -- ./candran/can-parser/validator.lua:82 -if not status then -- ./candran/can-parser/validator.lua:83 -return status, msg -- ./candran/can-parser/validator.lua:83 -end -- ./candran/can-parser/validator.lua:83 -end_scope(env) -- ./candran/can-parser/validator.lua:84 -end_function(env) -- ./candran/can-parser/validator.lua:85 -return true -- ./candran/can-parser/validator.lua:86 -end -- ./candran/can-parser/validator.lua:86 -local function traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:89 -new_function(env) -- ./candran/can-parser/validator.lua:90 -new_scope(env) -- ./candran/can-parser/validator.lua:91 -local status, msg = traverse_block(env, exp[1]) -- ./candran/can-parser/validator.lua:92 -if not status then -- ./candran/can-parser/validator.lua:93 -return status, msg -- ./candran/can-parser/validator.lua:93 -end -- ./candran/can-parser/validator.lua:93 -end_scope(env) -- ./candran/can-parser/validator.lua:94 -end_function(env) -- ./candran/can-parser/validator.lua:95 -return true -- ./candran/can-parser/validator.lua:96 -end -- ./candran/can-parser/validator.lua:96 -local function traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:99 -new_function(env) -- ./candran/can-parser/validator.lua:100 -new_scope(env) -- ./candran/can-parser/validator.lua:101 -exp["tag"] = exp["tag"]:gsub("Expr$", "") -- ./candran/can-parser/validator.lua:102 -local status, msg = traverse_stm(env, exp) -- ./candran/can-parser/validator.lua:103 -exp["tag"] = exp["tag"] .. "Expr" -- ./candran/can-parser/validator.lua:104 -if not status then -- ./candran/can-parser/validator.lua:105 -return status, msg -- ./candran/can-parser/validator.lua:105 -end -- ./candran/can-parser/validator.lua:105 -end_scope(env) -- ./candran/can-parser/validator.lua:106 -end_function(env) -- ./candran/can-parser/validator.lua:107 -return true -- ./candran/can-parser/validator.lua:108 -end -- ./candran/can-parser/validator.lua:108 -local function traverse_op(env, exp) -- ./candran/can-parser/validator.lua:111 -local status, msg = traverse_exp(env, exp[2]) -- ./candran/can-parser/validator.lua:112 -if not status then -- ./candran/can-parser/validator.lua:113 -return status, msg -- ./candran/can-parser/validator.lua:113 -end -- ./candran/can-parser/validator.lua:113 -if exp[3] then -- ./candran/can-parser/validator.lua:114 -status, msg = traverse_exp(env, exp[3]) -- ./candran/can-parser/validator.lua:115 -if not status then -- ./candran/can-parser/validator.lua:116 -return status, msg -- ./candran/can-parser/validator.lua:116 -end -- ./candran/can-parser/validator.lua:116 -end -- ./candran/can-parser/validator.lua:116 -return true -- ./candran/can-parser/validator.lua:118 -end -- ./candran/can-parser/validator.lua:118 -local function traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:121 -local status, msg = traverse_exp(env, exp[1]) -- ./candran/can-parser/validator.lua:122 -if not status then -- ./candran/can-parser/validator.lua:123 -return status, msg -- ./candran/can-parser/validator.lua:123 -end -- ./candran/can-parser/validator.lua:123 -return true -- ./candran/can-parser/validator.lua:124 -end -- ./candran/can-parser/validator.lua:124 -local function traverse_table(env, fieldlist) -- ./candran/can-parser/validator.lua:127 -for k, v in ipairs(fieldlist) do -- ./candran/can-parser/validator.lua:128 -local tag = v["tag"] -- ./candran/can-parser/validator.lua:129 -if tag == "Pair" then -- ./candran/can-parser/validator.lua:130 -local status, msg = traverse_exp(env, v[1]) -- ./candran/can-parser/validator.lua:131 -if not status then -- ./candran/can-parser/validator.lua:132 -return status, msg -- ./candran/can-parser/validator.lua:132 -end -- ./candran/can-parser/validator.lua:132 -status, msg = traverse_exp(env, v[2]) -- ./candran/can-parser/validator.lua:133 -if not status then -- ./candran/can-parser/validator.lua:134 -return status, msg -- ./candran/can-parser/validator.lua:134 -end -- ./candran/can-parser/validator.lua:134 -else -- ./candran/can-parser/validator.lua:134 -local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:136 -if not status then -- ./candran/can-parser/validator.lua:137 -return status, msg -- ./candran/can-parser/validator.lua:137 -end -- ./candran/can-parser/validator.lua:137 -end -- ./candran/can-parser/validator.lua:137 -end -- ./candran/can-parser/validator.lua:137 -return true -- ./candran/can-parser/validator.lua:140 -end -- ./candran/can-parser/validator.lua:140 -local function traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:143 -if not env["function"][env["fscope"]]["is_vararg"] then -- ./candran/can-parser/validator.lua:144 -local msg = "cannot use '...' outside a vararg function" -- ./candran/can-parser/validator.lua:145 -return nil, syntaxerror(env["errorinfo"], exp["pos"], msg) -- ./candran/can-parser/validator.lua:146 -end -- ./candran/can-parser/validator.lua:146 -return true -- ./candran/can-parser/validator.lua:148 -end -- ./candran/can-parser/validator.lua:148 -local function traverse_call(env, call) -- ./candran/can-parser/validator.lua:151 -local status, msg = traverse_exp(env, call[1]) -- ./candran/can-parser/validator.lua:152 -if not status then -- ./candran/can-parser/validator.lua:153 -return status, msg -- ./candran/can-parser/validator.lua:153 -end -- ./candran/can-parser/validator.lua:153 -for i = 2, # call do -- ./candran/can-parser/validator.lua:154 -status, msg = traverse_exp(env, call[i]) -- ./candran/can-parser/validator.lua:155 -if not status then -- ./candran/can-parser/validator.lua:156 -return status, msg -- ./candran/can-parser/validator.lua:156 -end -- ./candran/can-parser/validator.lua:156 -end -- ./candran/can-parser/validator.lua:156 -return true -- ./candran/can-parser/validator.lua:158 -end -- ./candran/can-parser/validator.lua:158 -local function traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:161 -local status, msg = traverse_varlist(env, stm[1]) -- ./candran/can-parser/validator.lua:162 -if not status then -- ./candran/can-parser/validator.lua:163 -return status, msg -- ./candran/can-parser/validator.lua:163 -end -- ./candran/can-parser/validator.lua:163 -status, msg = traverse_explist(env, stm[# stm]) -- ./candran/can-parser/validator.lua:164 -if not status then -- ./candran/can-parser/validator.lua:165 -return status, msg -- ./candran/can-parser/validator.lua:165 -end -- ./candran/can-parser/validator.lua:165 -return true -- ./candran/can-parser/validator.lua:166 -end -- ./candran/can-parser/validator.lua:166 -local function traverse_break(env, stm) -- ./candran/can-parser/validator.lua:169 -if not insideloop(env) then -- ./candran/can-parser/validator.lua:170 -local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:171 -return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:172 -end -- ./candran/can-parser/validator.lua:172 -return true -- ./candran/can-parser/validator.lua:174 -end -- ./candran/can-parser/validator.lua:174 -local function traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:177 -if not insideloop(env) then -- ./candran/can-parser/validator.lua:178 -local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:179 -return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:180 -end -- ./candran/can-parser/validator.lua:180 -return true -- ./candran/can-parser/validator.lua:182 -end -- ./candran/can-parser/validator.lua:182 -local function traverse_push(env, stm) -- ./candran/can-parser/validator.lua:185 -local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:186 -if not status then -- ./candran/can-parser/validator.lua:187 -return status, msg -- ./candran/can-parser/validator.lua:187 -end -- ./candran/can-parser/validator.lua:187 -return true -- ./candran/can-parser/validator.lua:188 -end -- ./candran/can-parser/validator.lua:188 -local function traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:191 -begin_loop(env) -- ./candran/can-parser/validator.lua:192 -new_scope(env) -- ./candran/can-parser/validator.lua:193 -local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:194 -if not status then -- ./candran/can-parser/validator.lua:195 -return status, msg -- ./candran/can-parser/validator.lua:195 -end -- ./candran/can-parser/validator.lua:195 -status, msg = traverse_block(env, stm[3]) -- ./candran/can-parser/validator.lua:196 -if not status then -- ./candran/can-parser/validator.lua:197 -return status, msg -- ./candran/can-parser/validator.lua:197 -end -- ./candran/can-parser/validator.lua:197 -end_scope(env) -- ./candran/can-parser/validator.lua:198 -end_loop(env) -- ./candran/can-parser/validator.lua:199 -return true -- ./candran/can-parser/validator.lua:200 -end -- ./candran/can-parser/validator.lua:200 -local function traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:203 -local status, msg -- ./candran/can-parser/validator.lua:204 -begin_loop(env) -- ./candran/can-parser/validator.lua:205 -new_scope(env) -- ./candran/can-parser/validator.lua:206 -status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:207 -if not status then -- ./candran/can-parser/validator.lua:208 -return status, msg -- ./candran/can-parser/validator.lua:208 -end -- ./candran/can-parser/validator.lua:208 -status, msg = traverse_exp(env, stm[3]) -- ./candran/can-parser/validator.lua:209 -if not status then -- ./candran/can-parser/validator.lua:210 -return status, msg -- ./candran/can-parser/validator.lua:210 -end -- ./candran/can-parser/validator.lua:210 -if stm[5] then -- ./candran/can-parser/validator.lua:211 -status, msg = traverse_exp(env, stm[4]) -- ./candran/can-parser/validator.lua:212 -if not status then -- ./candran/can-parser/validator.lua:213 -return status, msg -- ./candran/can-parser/validator.lua:213 -end -- ./candran/can-parser/validator.lua:213 -status, msg = traverse_block(env, stm[5]) -- ./candran/can-parser/validator.lua:214 -if not status then -- ./candran/can-parser/validator.lua:215 -return status, msg -- ./candran/can-parser/validator.lua:215 -end -- ./candran/can-parser/validator.lua:215 -else -- ./candran/can-parser/validator.lua:215 -status, msg = traverse_block(env, stm[4]) -- ./candran/can-parser/validator.lua:217 -if not status then -- ./candran/can-parser/validator.lua:218 -return status, msg -- ./candran/can-parser/validator.lua:218 -end -- ./candran/can-parser/validator.lua:218 -end -- ./candran/can-parser/validator.lua:218 -end_scope(env) -- ./candran/can-parser/validator.lua:220 -end_loop(env) -- ./candran/can-parser/validator.lua:221 -return true -- ./candran/can-parser/validator.lua:222 +local function set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:64 +env["function"][env["fscope"]]["is_vararg"] = is_vararg -- ./candran/can-parser/validator.lua:65 +end -- ./candran/can-parser/validator.lua:65 +local traverse_stm, traverse_exp, traverse_var -- ./candran/can-parser/validator.lua:68 +local traverse_block, traverse_explist, traverse_varlist, traverse_parlist -- ./candran/can-parser/validator.lua:69 +traverse_parlist = function(env, parlist) -- ./candran/can-parser/validator.lua:71 +local len = # parlist -- ./candran/can-parser/validator.lua:72 +local is_vararg = false -- ./candran/can-parser/validator.lua:73 +if len > 0 and parlist[len]["tag"] == "ParDots" then -- ./candran/can-parser/validator.lua:74 +is_vararg = true -- ./candran/can-parser/validator.lua:75 +end -- ./candran/can-parser/validator.lua:75 +set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:77 +return true -- ./candran/can-parser/validator.lua:78 +end -- ./candran/can-parser/validator.lua:78 +local function traverse_function(env, exp) -- ./candran/can-parser/validator.lua:81 +new_function(env) -- ./candran/can-parser/validator.lua:82 +new_scope(env) -- ./candran/can-parser/validator.lua:83 +local status, msg = traverse_parlist(env, exp[1]) -- ./candran/can-parser/validator.lua:84 +if not status then -- ./candran/can-parser/validator.lua:85 +return status, msg -- ./candran/can-parser/validator.lua:85 +end -- ./candran/can-parser/validator.lua:85 +status, msg = traverse_block(env, exp[2]) -- ./candran/can-parser/validator.lua:86 +if not status then -- ./candran/can-parser/validator.lua:87 +return status, msg -- ./candran/can-parser/validator.lua:87 +end -- ./candran/can-parser/validator.lua:87 +end_scope(env) -- ./candran/can-parser/validator.lua:88 +end_function(env) -- ./candran/can-parser/validator.lua:89 +return true -- ./candran/can-parser/validator.lua:90 +end -- ./candran/can-parser/validator.lua:90 +local function traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:93 +new_function(env) -- ./candran/can-parser/validator.lua:94 +new_scope(env) -- ./candran/can-parser/validator.lua:95 +local status, msg = traverse_block(env, exp[1]) -- ./candran/can-parser/validator.lua:96 +if not status then -- ./candran/can-parser/validator.lua:97 +return status, msg -- ./candran/can-parser/validator.lua:97 +end -- ./candran/can-parser/validator.lua:97 +end_scope(env) -- ./candran/can-parser/validator.lua:98 +end_function(env) -- ./candran/can-parser/validator.lua:99 +return true -- ./candran/can-parser/validator.lua:100 +end -- ./candran/can-parser/validator.lua:100 +local function traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:103 +new_function(env) -- ./candran/can-parser/validator.lua:104 +new_scope(env) -- ./candran/can-parser/validator.lua:105 +exp["tag"] = exp["tag"]:gsub("Expr$", "") -- ./candran/can-parser/validator.lua:106 +local status, msg = traverse_stm(env, exp) -- ./candran/can-parser/validator.lua:107 +exp["tag"] = exp["tag"] .. "Expr" -- ./candran/can-parser/validator.lua:108 +if not status then -- ./candran/can-parser/validator.lua:109 +return status, msg -- ./candran/can-parser/validator.lua:109 +end -- ./candran/can-parser/validator.lua:109 +end_scope(env) -- ./candran/can-parser/validator.lua:110 +end_function(env) -- ./candran/can-parser/validator.lua:111 +return true -- ./candran/can-parser/validator.lua:112 +end -- ./candran/can-parser/validator.lua:112 +local function traverse_op(env, exp) -- ./candran/can-parser/validator.lua:115 +local status, msg = traverse_exp(env, exp[2]) -- ./candran/can-parser/validator.lua:116 +if not status then -- ./candran/can-parser/validator.lua:117 +return status, msg -- ./candran/can-parser/validator.lua:117 +end -- ./candran/can-parser/validator.lua:117 +if exp[3] then -- ./candran/can-parser/validator.lua:118 +status, msg = traverse_exp(env, exp[3]) -- ./candran/can-parser/validator.lua:119 +if not status then -- ./candran/can-parser/validator.lua:120 +return status, msg -- ./candran/can-parser/validator.lua:120 +end -- ./candran/can-parser/validator.lua:120 +end -- ./candran/can-parser/validator.lua:120 +return true -- ./candran/can-parser/validator.lua:122 +end -- ./candran/can-parser/validator.lua:122 +local function traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:125 +local status, msg = traverse_exp(env, exp[1]) -- ./candran/can-parser/validator.lua:126 +if not status then -- ./candran/can-parser/validator.lua:127 +return status, msg -- ./candran/can-parser/validator.lua:127 +end -- ./candran/can-parser/validator.lua:127 +return true -- ./candran/can-parser/validator.lua:128 +end -- ./candran/can-parser/validator.lua:128 +local function traverse_table(env, fieldlist) -- ./candran/can-parser/validator.lua:131 +for k, v in ipairs(fieldlist) do -- ./candran/can-parser/validator.lua:132 +local tag = v["tag"] -- ./candran/can-parser/validator.lua:133 +if tag == "Pair" then -- ./candran/can-parser/validator.lua:134 +local status, msg = traverse_exp(env, v[1]) -- ./candran/can-parser/validator.lua:135 +if not status then -- ./candran/can-parser/validator.lua:136 +return status, msg -- ./candran/can-parser/validator.lua:136 +end -- ./candran/can-parser/validator.lua:136 +status, msg = traverse_exp(env, v[2]) -- ./candran/can-parser/validator.lua:137 +if not status then -- ./candran/can-parser/validator.lua:138 +return status, msg -- ./candran/can-parser/validator.lua:138 +end -- ./candran/can-parser/validator.lua:138 +else -- ./candran/can-parser/validator.lua:138 +local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:140 +if not status then -- ./candran/can-parser/validator.lua:141 +return status, msg -- ./candran/can-parser/validator.lua:141 +end -- ./candran/can-parser/validator.lua:141 +end -- ./candran/can-parser/validator.lua:141 +end -- ./candran/can-parser/validator.lua:141 +return true -- ./candran/can-parser/validator.lua:144 +end -- ./candran/can-parser/validator.lua:144 +local function traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:147 +if not env["function"][env["fscope"]]["is_vararg"] then -- ./candran/can-parser/validator.lua:148 +local msg = "cannot use '...' outside a vararg function" -- ./candran/can-parser/validator.lua:149 +return nil, syntaxerror(env["errorinfo"], exp["pos"], msg) -- ./candran/can-parser/validator.lua:150 +end -- ./candran/can-parser/validator.lua:150 +return true -- ./candran/can-parser/validator.lua:152 +end -- ./candran/can-parser/validator.lua:152 +local function traverse_call(env, call) -- ./candran/can-parser/validator.lua:155 +local status, msg = traverse_exp(env, call[1]) -- ./candran/can-parser/validator.lua:156 +if not status then -- ./candran/can-parser/validator.lua:157 +return status, msg -- ./candran/can-parser/validator.lua:157 +end -- ./candran/can-parser/validator.lua:157 +for i = 2, # call do -- ./candran/can-parser/validator.lua:158 +status, msg = traverse_exp(env, call[i]) -- ./candran/can-parser/validator.lua:159 +if not status then -- ./candran/can-parser/validator.lua:160 +return status, msg -- ./candran/can-parser/validator.lua:160 +end -- ./candran/can-parser/validator.lua:160 +end -- ./candran/can-parser/validator.lua:160 +return true -- ./candran/can-parser/validator.lua:162 +end -- ./candran/can-parser/validator.lua:162 +local function traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:165 +local status, msg = traverse_varlist(env, stm[1]) -- ./candran/can-parser/validator.lua:166 +if not status then -- ./candran/can-parser/validator.lua:167 +return status, msg -- ./candran/can-parser/validator.lua:167 +end -- ./candran/can-parser/validator.lua:167 +status, msg = traverse_explist(env, stm[# stm]) -- ./candran/can-parser/validator.lua:168 +if not status then -- ./candran/can-parser/validator.lua:169 +return status, msg -- ./candran/can-parser/validator.lua:169 +end -- ./candran/can-parser/validator.lua:169 +return true -- ./candran/can-parser/validator.lua:170 +end -- ./candran/can-parser/validator.lua:170 +local function traverse_break(env, stm) -- ./candran/can-parser/validator.lua:173 +if not insideloop(env) then -- ./candran/can-parser/validator.lua:174 +local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:175 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:176 +end -- ./candran/can-parser/validator.lua:176 +return true -- ./candran/can-parser/validator.lua:178 +end -- ./candran/can-parser/validator.lua:178 +local function traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:181 +if not insideloop(env) then -- ./candran/can-parser/validator.lua:182 +local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:183 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:184 +end -- ./candran/can-parser/validator.lua:184 +return true -- ./candran/can-parser/validator.lua:186 +end -- ./candran/can-parser/validator.lua:186 +local function traverse_push(env, stm) -- ./candran/can-parser/validator.lua:189 +local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:190 +if not status then -- ./candran/can-parser/validator.lua:191 +return status, msg -- ./candran/can-parser/validator.lua:191 +end -- ./candran/can-parser/validator.lua:191 +return true -- ./candran/can-parser/validator.lua:192 +end -- ./candran/can-parser/validator.lua:192 +local function traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:195 +begin_loop(env) -- ./candran/can-parser/validator.lua:196 +new_scope(env) -- ./candran/can-parser/validator.lua:197 +local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:198 +if not status then -- ./candran/can-parser/validator.lua:199 +return status, msg -- ./candran/can-parser/validator.lua:199 +end -- ./candran/can-parser/validator.lua:199 +status, msg = traverse_block(env, stm[3]) -- ./candran/can-parser/validator.lua:200 +if not status then -- ./candran/can-parser/validator.lua:201 +return status, msg -- ./candran/can-parser/validator.lua:201 +end -- ./candran/can-parser/validator.lua:201 +end_scope(env) -- ./candran/can-parser/validator.lua:202 +end_loop(env) -- ./candran/can-parser/validator.lua:203 +return true -- ./candran/can-parser/validator.lua:204 +end -- ./candran/can-parser/validator.lua:204 +local function traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:207 +local status, msg -- ./candran/can-parser/validator.lua:208 +begin_loop(env) -- ./candran/can-parser/validator.lua:209 +new_scope(env) -- ./candran/can-parser/validator.lua:210 +status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:211 +if not status then -- ./candran/can-parser/validator.lua:212 +return status, msg -- ./candran/can-parser/validator.lua:212 +end -- ./candran/can-parser/validator.lua:212 +status, msg = traverse_exp(env, stm[3]) -- ./candran/can-parser/validator.lua:213 +if not status then -- ./candran/can-parser/validator.lua:214 +return status, msg -- ./candran/can-parser/validator.lua:214 +end -- ./candran/can-parser/validator.lua:214 +if stm[5] then -- ./candran/can-parser/validator.lua:215 +status, msg = traverse_exp(env, stm[4]) -- ./candran/can-parser/validator.lua:216 +if not status then -- ./candran/can-parser/validator.lua:217 +return status, msg -- ./candran/can-parser/validator.lua:217 +end -- ./candran/can-parser/validator.lua:217 +status, msg = traverse_block(env, stm[5]) -- ./candran/can-parser/validator.lua:218 +if not status then -- ./candran/can-parser/validator.lua:219 +return status, msg -- ./candran/can-parser/validator.lua:219 +end -- ./candran/can-parser/validator.lua:219 +else -- ./candran/can-parser/validator.lua:219 +status, msg = traverse_block(env, stm[4]) -- ./candran/can-parser/validator.lua:221 +if not status then -- ./candran/can-parser/validator.lua:222 +return status, msg -- ./candran/can-parser/validator.lua:222 end -- ./candran/can-parser/validator.lua:222 -local function traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:225 -local status, msg = set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:226 -if not status then -- ./candran/can-parser/validator.lua:227 -return status, msg -- ./candran/can-parser/validator.lua:227 -end -- ./candran/can-parser/validator.lua:227 -return true -- ./candran/can-parser/validator.lua:228 -end -- ./candran/can-parser/validator.lua:228 -local function traverse_let(env, stm) -- ./candran/can-parser/validator.lua:231 -local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:232 -if not status then -- ./candran/can-parser/validator.lua:233 -return status, msg -- ./candran/can-parser/validator.lua:233 -end -- ./candran/can-parser/validator.lua:233 -return true -- ./candran/can-parser/validator.lua:234 -end -- ./candran/can-parser/validator.lua:234 -local function traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:237 -local status, msg = traverse_exp(env, stm[2][1]) -- ./candran/can-parser/validator.lua:238 -if not status then -- ./candran/can-parser/validator.lua:239 -return status, msg -- ./candran/can-parser/validator.lua:239 -end -- ./candran/can-parser/validator.lua:239 -return true -- ./candran/can-parser/validator.lua:240 -end -- ./candran/can-parser/validator.lua:240 -local function traverse_if(env, stm) -- ./candran/can-parser/validator.lua:243 -local len = # stm -- ./candran/can-parser/validator.lua:244 -if len % 2 == 0 then -- ./candran/can-parser/validator.lua:245 -for i = 1, len, 2 do -- ./candran/can-parser/validator.lua:246 -local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:247 -if not status then -- ./candran/can-parser/validator.lua:248 -return status, msg -- ./candran/can-parser/validator.lua:248 -end -- ./candran/can-parser/validator.lua:248 -status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:249 -if not status then -- ./candran/can-parser/validator.lua:250 -return status, msg -- ./candran/can-parser/validator.lua:250 -end -- ./candran/can-parser/validator.lua:250 -end -- ./candran/can-parser/validator.lua:250 -else -- ./candran/can-parser/validator.lua:250 -for i = 1, len - 1, 2 do -- ./candran/can-parser/validator.lua:253 -local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:254 -if not status then -- ./candran/can-parser/validator.lua:255 -return status, msg -- ./candran/can-parser/validator.lua:255 -end -- ./candran/can-parser/validator.lua:255 -status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:256 -if not status then -- ./candran/can-parser/validator.lua:257 -return status, msg -- ./candran/can-parser/validator.lua:257 -end -- ./candran/can-parser/validator.lua:257 -end -- ./candran/can-parser/validator.lua:257 -local status, msg = traverse_block(env, stm[len]) -- ./candran/can-parser/validator.lua:259 -if not status then -- ./candran/can-parser/validator.lua:260 -return status, msg -- ./candran/can-parser/validator.lua:260 -end -- ./candran/can-parser/validator.lua:260 -end -- ./candran/can-parser/validator.lua:260 -return true -- ./candran/can-parser/validator.lua:262 -end -- ./candran/can-parser/validator.lua:262 -local function traverse_label(env, stm) -- ./candran/can-parser/validator.lua:265 -local status, msg = set_label(env, stm[1], stm["pos"]) -- ./candran/can-parser/validator.lua:266 -if not status then -- ./candran/can-parser/validator.lua:267 -return status, msg -- ./candran/can-parser/validator.lua:267 -end -- ./candran/can-parser/validator.lua:267 -return true -- ./candran/can-parser/validator.lua:268 -end -- ./candran/can-parser/validator.lua:268 -local function traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:271 -begin_loop(env) -- ./candran/can-parser/validator.lua:272 -local status, msg = traverse_block(env, stm[1]) -- ./candran/can-parser/validator.lua:273 -if not status then -- ./candran/can-parser/validator.lua:274 -return status, msg -- ./candran/can-parser/validator.lua:274 -end -- ./candran/can-parser/validator.lua:274 -status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:275 -if not status then -- ./candran/can-parser/validator.lua:276 -return status, msg -- ./candran/can-parser/validator.lua:276 -end -- ./candran/can-parser/validator.lua:276 -end_loop(env) -- ./candran/can-parser/validator.lua:277 -return true -- ./candran/can-parser/validator.lua:278 +end -- ./candran/can-parser/validator.lua:222 +end_scope(env) -- ./candran/can-parser/validator.lua:224 +end_loop(env) -- ./candran/can-parser/validator.lua:225 +return true -- ./candran/can-parser/validator.lua:226 +end -- ./candran/can-parser/validator.lua:226 +local function traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:229 +local status, msg = set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:230 +if not status then -- ./candran/can-parser/validator.lua:231 +return status, msg -- ./candran/can-parser/validator.lua:231 +end -- ./candran/can-parser/validator.lua:231 +return true -- ./candran/can-parser/validator.lua:232 +end -- ./candran/can-parser/validator.lua:232 +local function traverse_let(env, stm) -- ./candran/can-parser/validator.lua:235 +local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:236 +if not status then -- ./candran/can-parser/validator.lua:237 +return status, msg -- ./candran/can-parser/validator.lua:237 +end -- ./candran/can-parser/validator.lua:237 +return true -- ./candran/can-parser/validator.lua:238 +end -- ./candran/can-parser/validator.lua:238 +local function traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:241 +local status, msg = traverse_exp(env, stm[2][1]) -- ./candran/can-parser/validator.lua:242 +if not status then -- ./candran/can-parser/validator.lua:243 +return status, msg -- ./candran/can-parser/validator.lua:243 +end -- ./candran/can-parser/validator.lua:243 +return true -- ./candran/can-parser/validator.lua:244 +end -- ./candran/can-parser/validator.lua:244 +local function traverse_if(env, stm) -- ./candran/can-parser/validator.lua:247 +local len = # stm -- ./candran/can-parser/validator.lua:248 +if len % 2 == 0 then -- ./candran/can-parser/validator.lua:249 +for i = 1, len, 2 do -- ./candran/can-parser/validator.lua:250 +local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:251 +if not status then -- ./candran/can-parser/validator.lua:252 +return status, msg -- ./candran/can-parser/validator.lua:252 +end -- ./candran/can-parser/validator.lua:252 +status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:253 +if not status then -- ./candran/can-parser/validator.lua:254 +return status, msg -- ./candran/can-parser/validator.lua:254 +end -- ./candran/can-parser/validator.lua:254 +end -- ./candran/can-parser/validator.lua:254 +else -- ./candran/can-parser/validator.lua:254 +for i = 1, len - 1, 2 do -- ./candran/can-parser/validator.lua:257 +local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:258 +if not status then -- ./candran/can-parser/validator.lua:259 +return status, msg -- ./candran/can-parser/validator.lua:259 +end -- ./candran/can-parser/validator.lua:259 +status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:260 +if not status then -- ./candran/can-parser/validator.lua:261 +return status, msg -- ./candran/can-parser/validator.lua:261 +end -- ./candran/can-parser/validator.lua:261 +end -- ./candran/can-parser/validator.lua:261 +local status, msg = traverse_block(env, stm[len]) -- ./candran/can-parser/validator.lua:263 +if not status then -- ./candran/can-parser/validator.lua:264 +return status, msg -- ./candran/can-parser/validator.lua:264 +end -- ./candran/can-parser/validator.lua:264 +end -- ./candran/can-parser/validator.lua:264 +return true -- ./candran/can-parser/validator.lua:266 +end -- ./candran/can-parser/validator.lua:266 +local function traverse_label(env, stm) -- ./candran/can-parser/validator.lua:269 +local status, msg = set_label(env, stm[1], stm["pos"]) -- ./candran/can-parser/validator.lua:270 +if not status then -- ./candran/can-parser/validator.lua:271 +return status, msg -- ./candran/can-parser/validator.lua:271 +end -- ./candran/can-parser/validator.lua:271 +return true -- ./candran/can-parser/validator.lua:272 +end -- ./candran/can-parser/validator.lua:272 +local function traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:275 +begin_loop(env) -- ./candran/can-parser/validator.lua:276 +local status, msg = traverse_block(env, stm[1]) -- ./candran/can-parser/validator.lua:277 +if not status then -- ./candran/can-parser/validator.lua:278 +return status, msg -- ./candran/can-parser/validator.lua:278 end -- ./candran/can-parser/validator.lua:278 -local function traverse_return(env, stm) -- ./candran/can-parser/validator.lua:281 -local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:282 -if not status then -- ./candran/can-parser/validator.lua:283 -return status, msg -- ./candran/can-parser/validator.lua:283 -end -- ./candran/can-parser/validator.lua:283 -return true -- ./candran/can-parser/validator.lua:284 -end -- ./candran/can-parser/validator.lua:284 -local function traverse_while(env, stm) -- ./candran/can-parser/validator.lua:287 -begin_loop(env) -- ./candran/can-parser/validator.lua:288 -local status, msg = traverse_exp(env, stm[1]) -- ./candran/can-parser/validator.lua:289 -if not status then -- ./candran/can-parser/validator.lua:290 -return status, msg -- ./candran/can-parser/validator.lua:290 -end -- ./candran/can-parser/validator.lua:290 -status, msg = traverse_block(env, stm[2]) -- ./candran/can-parser/validator.lua:291 -if not status then -- ./candran/can-parser/validator.lua:292 -return status, msg -- ./candran/can-parser/validator.lua:292 -end -- ./candran/can-parser/validator.lua:292 -end_loop(env) -- ./candran/can-parser/validator.lua:293 -return true -- ./candran/can-parser/validator.lua:294 +status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:279 +if not status then -- ./candran/can-parser/validator.lua:280 +return status, msg -- ./candran/can-parser/validator.lua:280 +end -- ./candran/can-parser/validator.lua:280 +end_loop(env) -- ./candran/can-parser/validator.lua:281 +return true -- ./candran/can-parser/validator.lua:282 +end -- ./candran/can-parser/validator.lua:282 +local function traverse_return(env, stm) -- ./candran/can-parser/validator.lua:285 +local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:286 +if not status then -- ./candran/can-parser/validator.lua:287 +return status, msg -- ./candran/can-parser/validator.lua:287 +end -- ./candran/can-parser/validator.lua:287 +return true -- ./candran/can-parser/validator.lua:288 +end -- ./candran/can-parser/validator.lua:288 +local function traverse_while(env, stm) -- ./candran/can-parser/validator.lua:291 +begin_loop(env) -- ./candran/can-parser/validator.lua:292 +local status, msg = traverse_exp(env, stm[1]) -- ./candran/can-parser/validator.lua:293 +if not status then -- ./candran/can-parser/validator.lua:294 +return status, msg -- ./candran/can-parser/validator.lua:294 end -- ./candran/can-parser/validator.lua:294 -traverse_var = function(env, var) -- ./candran/can-parser/validator.lua:297 -local tag = var["tag"] -- ./candran/can-parser/validator.lua:298 -if tag == "Id" then -- ./candran/can-parser/validator.lua:299 -return true -- ./candran/can-parser/validator.lua:300 -elseif tag == "Index" then -- ./candran/can-parser/validator.lua:301 -local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:302 -if not status then -- ./candran/can-parser/validator.lua:303 -return status, msg -- ./candran/can-parser/validator.lua:303 -end -- ./candran/can-parser/validator.lua:303 -status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:304 -if not status then -- ./candran/can-parser/validator.lua:305 -return status, msg -- ./candran/can-parser/validator.lua:305 -end -- ./candran/can-parser/validator.lua:305 -return true -- ./candran/can-parser/validator.lua:306 -elseif tag == "DestructuringId" then -- ./candran/can-parser/validator.lua:307 -return traverse_table(env, var) -- ./candran/can-parser/validator.lua:308 -else -- ./candran/can-parser/validator.lua:308 -error("expecting a variable, but got a " .. tag) -- ./candran/can-parser/validator.lua:310 -end -- ./candran/can-parser/validator.lua:310 -end -- ./candran/can-parser/validator.lua:310 -traverse_varlist = function(env, varlist) -- ./candran/can-parser/validator.lua:314 -for k, v in ipairs(varlist) do -- ./candran/can-parser/validator.lua:315 -local status, msg = traverse_var(env, v) -- ./candran/can-parser/validator.lua:316 -if not status then -- ./candran/can-parser/validator.lua:317 -return status, msg -- ./candran/can-parser/validator.lua:317 -end -- ./candran/can-parser/validator.lua:317 -end -- ./candran/can-parser/validator.lua:317 -return true -- ./candran/can-parser/validator.lua:319 -end -- ./candran/can-parser/validator.lua:319 -local function traverse_methodstub(env, var) -- ./candran/can-parser/validator.lua:322 -local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:323 -if not status then -- ./candran/can-parser/validator.lua:324 -return status, msg -- ./candran/can-parser/validator.lua:324 -end -- ./candran/can-parser/validator.lua:324 -status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:325 -if not status then -- ./candran/can-parser/validator.lua:326 -return status, msg -- ./candran/can-parser/validator.lua:326 -end -- ./candran/can-parser/validator.lua:326 -return true -- ./candran/can-parser/validator.lua:327 -end -- ./candran/can-parser/validator.lua:327 -local function traverse_safeindex(env, var) -- ./candran/can-parser/validator.lua:330 -local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:331 -if not status then -- ./candran/can-parser/validator.lua:332 -return status, msg -- ./candran/can-parser/validator.lua:332 -end -- ./candran/can-parser/validator.lua:332 -status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:333 -if not status then -- ./candran/can-parser/validator.lua:334 -return status, msg -- ./candran/can-parser/validator.lua:334 -end -- ./candran/can-parser/validator.lua:334 -return true -- ./candran/can-parser/validator.lua:335 -end -- ./candran/can-parser/validator.lua:335 -traverse_exp = function(env, exp) -- ./candran/can-parser/validator.lua:338 -local tag = exp["tag"] -- ./candran/can-parser/validator.lua:339 -if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- ./candran/can-parser/validator.lua:343 -return true -- ./candran/can-parser/validator.lua:344 -elseif tag == "Dots" then -- ./candran/can-parser/validator.lua:345 -return traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:346 -elseif tag == "Function" then -- ./candran/can-parser/validator.lua:347 -return traverse_function(env, exp) -- ./candran/can-parser/validator.lua:348 -elseif tag == "Table" then -- ./candran/can-parser/validator.lua:349 -return traverse_table(env, exp) -- ./candran/can-parser/validator.lua:350 -elseif tag == "Op" then -- ./candran/can-parser/validator.lua:351 -return traverse_op(env, exp) -- ./candran/can-parser/validator.lua:352 -elseif tag == "Paren" then -- ./candran/can-parser/validator.lua:353 -return traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:354 -elseif tag == "Call" or tag == "SafeCall" then -- ./candran/can-parser/validator.lua:355 -return traverse_call(env, exp) -- ./candran/can-parser/validator.lua:356 -elseif tag == "Id" or tag == "Index" then -- ./candran/can-parser/validator.lua:358 -return traverse_var(env, exp) -- ./candran/can-parser/validator.lua:359 -elseif tag == "SafeIndex" then -- ./candran/can-parser/validator.lua:360 -return traverse_safeindex(env, exp) -- ./candran/can-parser/validator.lua:361 -elseif tag == "TableCompr" then -- ./candran/can-parser/validator.lua:362 -return traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:363 -elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- ./candran/can-parser/validator.lua:364 -return traverse_methodstub(env, exp) -- ./candran/can-parser/validator.lua:365 -elseif tag:match("Expr$") then -- ./candran/can-parser/validator.lua:366 -return traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:367 -else -- ./candran/can-parser/validator.lua:367 -error("expecting an expression, but got a " .. tag) -- ./candran/can-parser/validator.lua:369 -end -- ./candran/can-parser/validator.lua:369 -end -- ./candran/can-parser/validator.lua:369 -traverse_explist = function(env, explist) -- ./candran/can-parser/validator.lua:373 -for k, v in ipairs(explist) do -- ./candran/can-parser/validator.lua:374 -local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:375 -if not status then -- ./candran/can-parser/validator.lua:376 -return status, msg -- ./candran/can-parser/validator.lua:376 -end -- ./candran/can-parser/validator.lua:376 -end -- ./candran/can-parser/validator.lua:376 -return true -- ./candran/can-parser/validator.lua:378 -end -- ./candran/can-parser/validator.lua:378 -traverse_stm = function(env, stm) -- ./candran/can-parser/validator.lua:381 -local tag = stm["tag"] -- ./candran/can-parser/validator.lua:382 -if tag == "Do" then -- ./candran/can-parser/validator.lua:383 -return traverse_block(env, stm) -- ./candran/can-parser/validator.lua:384 -elseif tag == "Set" then -- ./candran/can-parser/validator.lua:385 -return traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:386 -elseif tag == "While" then -- ./candran/can-parser/validator.lua:387 -return traverse_while(env, stm) -- ./candran/can-parser/validator.lua:388 -elseif tag == "Repeat" then -- ./candran/can-parser/validator.lua:389 -return traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:390 -elseif tag == "If" then -- ./candran/can-parser/validator.lua:391 -return traverse_if(env, stm) -- ./candran/can-parser/validator.lua:392 -elseif tag == "Fornum" then -- ./candran/can-parser/validator.lua:393 -return traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:394 -elseif tag == "Forin" then -- ./candran/can-parser/validator.lua:395 -return traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:396 -elseif tag == "Local" or tag == "Let" then -- ./candran/can-parser/validator.lua:398 -return traverse_let(env, stm) -- ./candran/can-parser/validator.lua:399 -elseif tag == "Localrec" then -- ./candran/can-parser/validator.lua:400 -return traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:401 -elseif tag == "Goto" then -- ./candran/can-parser/validator.lua:402 -return traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:403 -elseif tag == "Label" then -- ./candran/can-parser/validator.lua:404 -return traverse_label(env, stm) -- ./candran/can-parser/validator.lua:405 -elseif tag == "Return" then -- ./candran/can-parser/validator.lua:406 -return traverse_return(env, stm) -- ./candran/can-parser/validator.lua:407 -elseif tag == "Break" then -- ./candran/can-parser/validator.lua:408 -return traverse_break(env, stm) -- ./candran/can-parser/validator.lua:409 -elseif tag == "Call" then -- ./candran/can-parser/validator.lua:410 -return traverse_call(env, stm) -- ./candran/can-parser/validator.lua:411 -elseif tag == "Continue" then -- ./candran/can-parser/validator.lua:412 -return traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:413 -elseif tag == "Push" then -- ./candran/can-parser/validator.lua:414 -return traverse_push(env, stm) -- ./candran/can-parser/validator.lua:415 -else -- ./candran/can-parser/validator.lua:415 -error("expecting a statement, but got a " .. tag) -- ./candran/can-parser/validator.lua:417 -end -- ./candran/can-parser/validator.lua:417 -end -- ./candran/can-parser/validator.lua:417 -traverse_block = function(env, block) -- ./candran/can-parser/validator.lua:421 -local l = {} -- ./candran/can-parser/validator.lua:422 -new_scope(env) -- ./candran/can-parser/validator.lua:423 -for k, v in ipairs(block) do -- ./candran/can-parser/validator.lua:424 -local status, msg = traverse_stm(env, v) -- ./candran/can-parser/validator.lua:425 -if not status then -- ./candran/can-parser/validator.lua:426 -return status, msg -- ./candran/can-parser/validator.lua:426 -end -- ./candran/can-parser/validator.lua:426 -end -- ./candran/can-parser/validator.lua:426 -end_scope(env) -- ./candran/can-parser/validator.lua:428 -return true -- ./candran/can-parser/validator.lua:429 -end -- ./candran/can-parser/validator.lua:429 -local function traverse(ast, errorinfo) -- ./candran/can-parser/validator.lua:433 -assert(type(ast) == "table") -- ./candran/can-parser/validator.lua:434 -assert(type(errorinfo) == "table") -- ./candran/can-parser/validator.lua:435 -local env = { -- ./candran/can-parser/validator.lua:436 -["errorinfo"] = errorinfo, -- ./candran/can-parser/validator.lua:436 -["function"] = {} -- ./candran/can-parser/validator.lua:436 -} -- ./candran/can-parser/validator.lua:436 -new_function(env) -- ./candran/can-parser/validator.lua:437 -set_vararg(env, true) -- ./candran/can-parser/validator.lua:438 -local status, msg = traverse_block(env, ast) -- ./candran/can-parser/validator.lua:439 -if not status then -- ./candran/can-parser/validator.lua:440 -return status, msg -- ./candran/can-parser/validator.lua:440 -end -- ./candran/can-parser/validator.lua:440 -end_function(env) -- ./candran/can-parser/validator.lua:441 -status, msg = verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:442 -if not status then -- ./candran/can-parser/validator.lua:443 -return status, msg -- ./candran/can-parser/validator.lua:443 -end -- ./candran/can-parser/validator.lua:443 -return ast -- ./candran/can-parser/validator.lua:444 -end -- ./candran/can-parser/validator.lua:444 -return { -- ./candran/can-parser/validator.lua:447 -["validate"] = traverse, -- ./candran/can-parser/validator.lua:447 -["syntaxerror"] = syntaxerror -- ./candran/can-parser/validator.lua:447 -} -- ./candran/can-parser/validator.lua:447 -end -- ./candran/can-parser/validator.lua:447 -local validator = _() or validator -- ./candran/can-parser/validator.lua:451 -package["loaded"]["candran.can-parser.validator"] = validator or true -- ./candran/can-parser/validator.lua:452 -local function _() -- ./candran/can-parser/validator.lua:455 +status, msg = traverse_block(env, stm[2]) -- ./candran/can-parser/validator.lua:295 +if not status then -- ./candran/can-parser/validator.lua:296 +return status, msg -- ./candran/can-parser/validator.lua:296 +end -- ./candran/can-parser/validator.lua:296 +end_loop(env) -- ./candran/can-parser/validator.lua:297 +return true -- ./candran/can-parser/validator.lua:298 +end -- ./candran/can-parser/validator.lua:298 +traverse_var = function(env, var) -- ./candran/can-parser/validator.lua:301 +local tag = var["tag"] -- ./candran/can-parser/validator.lua:302 +if tag == "Id" then -- ./candran/can-parser/validator.lua:303 +return true -- ./candran/can-parser/validator.lua:304 +elseif tag == "Index" then -- ./candran/can-parser/validator.lua:305 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:306 +if not status then -- ./candran/can-parser/validator.lua:307 +return status, msg -- ./candran/can-parser/validator.lua:307 +end -- ./candran/can-parser/validator.lua:307 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:308 +if not status then -- ./candran/can-parser/validator.lua:309 +return status, msg -- ./candran/can-parser/validator.lua:309 +end -- ./candran/can-parser/validator.lua:309 +return true -- ./candran/can-parser/validator.lua:310 +elseif tag == "DestructuringId" then -- ./candran/can-parser/validator.lua:311 +return traverse_table(env, var) -- ./candran/can-parser/validator.lua:312 +else -- ./candran/can-parser/validator.lua:312 +error("expecting a variable, but got a " .. tag) -- ./candran/can-parser/validator.lua:314 +end -- ./candran/can-parser/validator.lua:314 +end -- ./candran/can-parser/validator.lua:314 +traverse_varlist = function(env, varlist) -- ./candran/can-parser/validator.lua:318 +for k, v in ipairs(varlist) do -- ./candran/can-parser/validator.lua:319 +local status, msg = traverse_var(env, v) -- ./candran/can-parser/validator.lua:320 +if not status then -- ./candran/can-parser/validator.lua:321 +return status, msg -- ./candran/can-parser/validator.lua:321 +end -- ./candran/can-parser/validator.lua:321 +end -- ./candran/can-parser/validator.lua:321 +return true -- ./candran/can-parser/validator.lua:323 +end -- ./candran/can-parser/validator.lua:323 +local function traverse_methodstub(env, var) -- ./candran/can-parser/validator.lua:326 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:327 +if not status then -- ./candran/can-parser/validator.lua:328 +return status, msg -- ./candran/can-parser/validator.lua:328 +end -- ./candran/can-parser/validator.lua:328 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:329 +if not status then -- ./candran/can-parser/validator.lua:330 +return status, msg -- ./candran/can-parser/validator.lua:330 +end -- ./candran/can-parser/validator.lua:330 +return true -- ./candran/can-parser/validator.lua:331 +end -- ./candran/can-parser/validator.lua:331 +local function traverse_safeindex(env, var) -- ./candran/can-parser/validator.lua:334 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:335 +if not status then -- ./candran/can-parser/validator.lua:336 +return status, msg -- ./candran/can-parser/validator.lua:336 +end -- ./candran/can-parser/validator.lua:336 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:337 +if not status then -- ./candran/can-parser/validator.lua:338 +return status, msg -- ./candran/can-parser/validator.lua:338 +end -- ./candran/can-parser/validator.lua:338 +return true -- ./candran/can-parser/validator.lua:339 +end -- ./candran/can-parser/validator.lua:339 +traverse_exp = function(env, exp) -- ./candran/can-parser/validator.lua:342 +local tag = exp["tag"] -- ./candran/can-parser/validator.lua:343 +if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- ./candran/can-parser/validator.lua:347 +return true -- ./candran/can-parser/validator.lua:348 +elseif tag == "Dots" then -- ./candran/can-parser/validator.lua:349 +return traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:350 +elseif tag == "Function" then -- ./candran/can-parser/validator.lua:351 +return traverse_function(env, exp) -- ./candran/can-parser/validator.lua:352 +elseif tag == "Table" then -- ./candran/can-parser/validator.lua:353 +return traverse_table(env, exp) -- ./candran/can-parser/validator.lua:354 +elseif tag == "Op" then -- ./candran/can-parser/validator.lua:355 +return traverse_op(env, exp) -- ./candran/can-parser/validator.lua:356 +elseif tag == "Paren" then -- ./candran/can-parser/validator.lua:357 +return traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:358 +elseif tag == "Call" or tag == "SafeCall" then -- ./candran/can-parser/validator.lua:359 +return traverse_call(env, exp) -- ./candran/can-parser/validator.lua:360 +elseif tag == "Id" or tag == "Index" then -- ./candran/can-parser/validator.lua:362 +return traverse_var(env, exp) -- ./candran/can-parser/validator.lua:363 +elseif tag == "SafeIndex" then -- ./candran/can-parser/validator.lua:364 +return traverse_safeindex(env, exp) -- ./candran/can-parser/validator.lua:365 +elseif tag == "TableCompr" then -- ./candran/can-parser/validator.lua:366 +return traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:367 +elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- ./candran/can-parser/validator.lua:368 +return traverse_methodstub(env, exp) -- ./candran/can-parser/validator.lua:369 +elseif tag:match("Expr$") then -- ./candran/can-parser/validator.lua:370 +return traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:371 +else -- ./candran/can-parser/validator.lua:371 +error("expecting an expression, but got a " .. tag) -- ./candran/can-parser/validator.lua:373 +end -- ./candran/can-parser/validator.lua:373 +end -- ./candran/can-parser/validator.lua:373 +traverse_explist = function(env, explist) -- ./candran/can-parser/validator.lua:377 +for k, v in ipairs(explist) do -- ./candran/can-parser/validator.lua:378 +local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:379 +if not status then -- ./candran/can-parser/validator.lua:380 +return status, msg -- ./candran/can-parser/validator.lua:380 +end -- ./candran/can-parser/validator.lua:380 +end -- ./candran/can-parser/validator.lua:380 +return true -- ./candran/can-parser/validator.lua:382 +end -- ./candran/can-parser/validator.lua:382 +traverse_stm = function(env, stm) -- ./candran/can-parser/validator.lua:385 +local tag = stm["tag"] -- ./candran/can-parser/validator.lua:386 +if tag == "Do" then -- ./candran/can-parser/validator.lua:387 +return traverse_block(env, stm) -- ./candran/can-parser/validator.lua:388 +elseif tag == "Set" then -- ./candran/can-parser/validator.lua:389 +return traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:390 +elseif tag == "While" then -- ./candran/can-parser/validator.lua:391 +return traverse_while(env, stm) -- ./candran/can-parser/validator.lua:392 +elseif tag == "Repeat" then -- ./candran/can-parser/validator.lua:393 +return traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:394 +elseif tag == "If" then -- ./candran/can-parser/validator.lua:395 +return traverse_if(env, stm) -- ./candran/can-parser/validator.lua:396 +elseif tag == "Fornum" then -- ./candran/can-parser/validator.lua:397 +return traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:398 +elseif tag == "Forin" then -- ./candran/can-parser/validator.lua:399 +return traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:400 +elseif tag == "Local" or tag == "Let" or tag == "Global" then -- ./candran/can-parser/validator.lua:403 +return traverse_let(env, stm) -- ./candran/can-parser/validator.lua:404 +elseif tag == "Localrec" or tag == "Globalrec" then -- ./candran/can-parser/validator.lua:406 +return traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:407 +elseif tag == "GlobalAll" then -- ./candran/can-parser/validator.lua:408 +return true -- ./candran/can-parser/validator.lua:409 +elseif tag == "Goto" then -- ./candran/can-parser/validator.lua:410 +return traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:411 +elseif tag == "Label" then -- ./candran/can-parser/validator.lua:412 +return traverse_label(env, stm) -- ./candran/can-parser/validator.lua:413 +elseif tag == "Return" then -- ./candran/can-parser/validator.lua:414 +return traverse_return(env, stm) -- ./candran/can-parser/validator.lua:415 +elseif tag == "Break" then -- ./candran/can-parser/validator.lua:416 +return traverse_break(env, stm) -- ./candran/can-parser/validator.lua:417 +elseif tag == "Call" then -- ./candran/can-parser/validator.lua:418 +return traverse_call(env, stm) -- ./candran/can-parser/validator.lua:419 +elseif tag == "Continue" then -- ./candran/can-parser/validator.lua:420 +return traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:421 +elseif tag == "Push" then -- ./candran/can-parser/validator.lua:422 +return traverse_push(env, stm) -- ./candran/can-parser/validator.lua:423 +else -- ./candran/can-parser/validator.lua:423 +error("expecting a statement, but got a " .. tag) -- ./candran/can-parser/validator.lua:425 +end -- ./candran/can-parser/validator.lua:425 +end -- ./candran/can-parser/validator.lua:425 +traverse_block = function(env, block) -- ./candran/can-parser/validator.lua:429 +local l = {} -- ./candran/can-parser/validator.lua:430 +new_scope(env) -- ./candran/can-parser/validator.lua:431 +for k, v in ipairs(block) do -- ./candran/can-parser/validator.lua:432 +local status, msg = traverse_stm(env, v) -- ./candran/can-parser/validator.lua:433 +if not status then -- ./candran/can-parser/validator.lua:434 +return status, msg -- ./candran/can-parser/validator.lua:434 +end -- ./candran/can-parser/validator.lua:434 +end -- ./candran/can-parser/validator.lua:434 +end_scope(env) -- ./candran/can-parser/validator.lua:436 +return true -- ./candran/can-parser/validator.lua:437 +end -- ./candran/can-parser/validator.lua:437 +local function traverse(ast, errorinfo) -- ./candran/can-parser/validator.lua:441 +assert(type(ast) == "table") -- ./candran/can-parser/validator.lua:442 +assert(type(errorinfo) == "table") -- ./candran/can-parser/validator.lua:443 +local env = { -- ./candran/can-parser/validator.lua:444 +["errorinfo"] = errorinfo, -- ./candran/can-parser/validator.lua:444 +["function"] = {} -- ./candran/can-parser/validator.lua:444 +} -- ./candran/can-parser/validator.lua:444 +new_function(env) -- ./candran/can-parser/validator.lua:445 +set_vararg(env, true) -- ./candran/can-parser/validator.lua:446 +local status, msg = traverse_block(env, ast) -- ./candran/can-parser/validator.lua:447 +if not status then -- ./candran/can-parser/validator.lua:448 +return status, msg -- ./candran/can-parser/validator.lua:448 +end -- ./candran/can-parser/validator.lua:448 +end_function(env) -- ./candran/can-parser/validator.lua:449 +status, msg = verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:450 +if not status then -- ./candran/can-parser/validator.lua:451 +return status, msg -- ./candran/can-parser/validator.lua:451 +end -- ./candran/can-parser/validator.lua:451 +return ast -- ./candran/can-parser/validator.lua:452 +end -- ./candran/can-parser/validator.lua:452 +return { -- ./candran/can-parser/validator.lua:455 +["validate"] = traverse, -- ./candran/can-parser/validator.lua:455 +["syntaxerror"] = syntaxerror -- ./candran/can-parser/validator.lua:455 +} -- ./candran/can-parser/validator.lua:455 +end -- ./candran/can-parser/validator.lua:455 +local validator = _() or validator -- ./candran/can-parser/validator.lua:459 +package["loaded"]["candran.can-parser.validator"] = validator or true -- ./candran/can-parser/validator.lua:460 +local function _() -- ./candran/can-parser/validator.lua:463 local pp = {} -- ./candran/can-parser/pp.lua:4 local block2str, stm2str, exp2str, var2str -- ./candran/can-parser/pp.lua:6 local explist2str, varlist2str, parlist2str, fieldlist2str -- ./candran/can-parser/pp.lua:7 @@ -6069,7 +7386,7 @@ str = str .. varlist2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:244 str = str .. explist2str(stm[2]) .. ", " -- ./candran/can-parser/pp.lua:245 str = str .. block2str(stm[3]) -- ./candran/can-parser/pp.lua:246 str = str .. " }" -- ./candran/can-parser/pp.lua:247 -elseif tag == "Local" then -- ./candran/can-parser/pp.lua:248 +elseif tag == "Local" or tag == "Global" then -- ./candran/can-parser/pp.lua:248 str = str .. "{ " -- ./candran/can-parser/pp.lua:249 str = str .. varlist2str(stm[1]) -- ./candran/can-parser/pp.lua:250 if # stm[2] > 0 then -- ./candran/can-parser/pp.lua:251 @@ -6078,7 +7395,7 @@ else -- ./candran/can-parser/pp.lua:252 str = str .. ", " .. "{ }" -- ./candran/can-parser/pp.lua:254 end -- ./candran/can-parser/pp.lua:254 str = str .. " }" -- ./candran/can-parser/pp.lua:256 -elseif tag == "Localrec" then -- ./candran/can-parser/pp.lua:257 +elseif tag == "Localrec" or tag == "Globalrec" then -- ./candran/can-parser/pp.lua:257 str = str .. "{ " -- ./candran/can-parser/pp.lua:258 str = str .. "{ " .. var2str(stm[1][1]) .. " }, " -- ./candran/can-parser/pp.lua:259 str = str .. "{ " .. exp2str(stm[2][1]) .. " }" -- ./candran/can-parser/pp.lua:260 @@ -6155,1193 +7472,1202 @@ end -- ./candran/can-parser/pp.lua:327 local pp = _() or pp -- ./candran/can-parser/pp.lua:331 package["loaded"]["candran.can-parser.pp"] = pp or true -- ./candran/can-parser/pp.lua:332 local function _() -- ./candran/can-parser/pp.lua:335 -local lpeg = require("lpeglabel") -- ./candran/can-parser/parser.lua:72 -lpeg["locale"](lpeg) -- ./candran/can-parser/parser.lua:74 -local P, S, V = lpeg["P"], lpeg["S"], lpeg["V"] -- ./candran/can-parser/parser.lua:76 -local C, Carg, Cb, Cc = lpeg["C"], lpeg["Carg"], lpeg["Cb"], lpeg["Cc"] -- ./candran/can-parser/parser.lua:77 -local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg["Cf"], lpeg["Cg"], lpeg["Cmt"], lpeg["Cp"], lpeg["Cs"], lpeg["Ct"] -- ./candran/can-parser/parser.lua:78 -local Rec, T = lpeg["Rec"], lpeg["T"] -- ./candran/can-parser/parser.lua:79 -local alpha, digit, alnum = lpeg["alpha"], lpeg["digit"], lpeg["alnum"] -- ./candran/can-parser/parser.lua:81 -local xdigit = lpeg["xdigit"] -- ./candran/can-parser/parser.lua:82 -local space = lpeg["space"] -- ./candran/can-parser/parser.lua:83 -local labels = { -- ./candran/can-parser/parser.lua:88 -{ -- ./candran/can-parser/parser.lua:89 -"ErrExtra", -- ./candran/can-parser/parser.lua:89 -"unexpected character(s), expected EOF" -- ./candran/can-parser/parser.lua:89 -}, -- ./candran/can-parser/parser.lua:89 -{ -- ./candran/can-parser/parser.lua:90 -"ErrInvalidStat", -- ./candran/can-parser/parser.lua:90 -"unexpected token, invalid start of statement" -- ./candran/can-parser/parser.lua:90 -}, -- ./candran/can-parser/parser.lua:90 +local lpeg = require("lpeglabel") -- ./candran/can-parser/parser.lua:75 +lpeg["locale"](lpeg) -- ./candran/can-parser/parser.lua:77 +local P, S, V = lpeg["P"], lpeg["S"], lpeg["V"] -- ./candran/can-parser/parser.lua:79 +local C, Carg, Cb, Cc = lpeg["C"], lpeg["Carg"], lpeg["Cb"], lpeg["Cc"] -- ./candran/can-parser/parser.lua:80 +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg["Cf"], lpeg["Cg"], lpeg["Cmt"], lpeg["Cp"], lpeg["Cs"], lpeg["Ct"] -- ./candran/can-parser/parser.lua:81 +local Rec, T = lpeg["Rec"], lpeg["T"] -- ./candran/can-parser/parser.lua:82 +local alpha, digit, alnum = lpeg["alpha"], lpeg["digit"], lpeg["alnum"] -- ./candran/can-parser/parser.lua:84 +local xdigit = lpeg["xdigit"] -- ./candran/can-parser/parser.lua:85 +local space = lpeg["space"] -- ./candran/can-parser/parser.lua:86 +local labels = { -- ./candran/can-parser/parser.lua:91 { -- ./candran/can-parser/parser.lua:92 -"ErrEndIf", -- ./candran/can-parser/parser.lua:92 -"expected 'end' to close the if statement" -- ./candran/can-parser/parser.lua:92 +"ErrExtra", -- ./candran/can-parser/parser.lua:92 +"unexpected character(s), expected EOF" -- ./candran/can-parser/parser.lua:92 }, -- ./candran/can-parser/parser.lua:92 { -- ./candran/can-parser/parser.lua:93 -"ErrExprIf", -- ./candran/can-parser/parser.lua:93 -"expected a condition after 'if'" -- ./candran/can-parser/parser.lua:93 +"ErrInvalidStat", -- ./candran/can-parser/parser.lua:93 +"unexpected token, invalid start of statement" -- ./candran/can-parser/parser.lua:93 }, -- ./candran/can-parser/parser.lua:93 -{ -- ./candran/can-parser/parser.lua:94 -"ErrThenIf", -- ./candran/can-parser/parser.lua:94 -"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:94 -}, -- ./candran/can-parser/parser.lua:94 { -- ./candran/can-parser/parser.lua:95 -"ErrExprEIf", -- ./candran/can-parser/parser.lua:95 -"expected a condition after 'elseif'" -- ./candran/can-parser/parser.lua:95 +"ErrEndIf", -- ./candran/can-parser/parser.lua:95 +"expected 'end' to close the if statement" -- ./candran/can-parser/parser.lua:95 }, -- ./candran/can-parser/parser.lua:95 { -- ./candran/can-parser/parser.lua:96 -"ErrThenEIf", -- ./candran/can-parser/parser.lua:96 -"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:96 +"ErrExprIf", -- ./candran/can-parser/parser.lua:96 +"expected a condition after 'if'" -- ./candran/can-parser/parser.lua:96 }, -- ./candran/can-parser/parser.lua:96 +{ -- ./candran/can-parser/parser.lua:97 +"ErrThenIf", -- ./candran/can-parser/parser.lua:97 +"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:97 +}, -- ./candran/can-parser/parser.lua:97 { -- ./candran/can-parser/parser.lua:98 -"ErrEndDo", -- ./candran/can-parser/parser.lua:98 -"expected 'end' to close the do block" -- ./candran/can-parser/parser.lua:98 +"ErrExprEIf", -- ./candran/can-parser/parser.lua:98 +"expected a condition after 'elseif'" -- ./candran/can-parser/parser.lua:98 }, -- ./candran/can-parser/parser.lua:98 { -- ./candran/can-parser/parser.lua:99 -"ErrExprWhile", -- ./candran/can-parser/parser.lua:99 -"expected a condition after 'while'" -- ./candran/can-parser/parser.lua:99 +"ErrThenEIf", -- ./candran/can-parser/parser.lua:99 +"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:99 }, -- ./candran/can-parser/parser.lua:99 -{ -- ./candran/can-parser/parser.lua:100 -"ErrDoWhile", -- ./candran/can-parser/parser.lua:100 -"expected 'do' after the condition" -- ./candran/can-parser/parser.lua:100 -}, -- ./candran/can-parser/parser.lua:100 { -- ./candran/can-parser/parser.lua:101 -"ErrEndWhile", -- ./candran/can-parser/parser.lua:101 -"expected 'end' to close the while loop" -- ./candran/can-parser/parser.lua:101 +"ErrEndDo", -- ./candran/can-parser/parser.lua:101 +"expected 'end' to close the do block" -- ./candran/can-parser/parser.lua:101 }, -- ./candran/can-parser/parser.lua:101 { -- ./candran/can-parser/parser.lua:102 -"ErrUntilRep", -- ./candran/can-parser/parser.lua:102 -"expected 'until' at the end of the repeat loop" -- ./candran/can-parser/parser.lua:102 +"ErrExprWhile", -- ./candran/can-parser/parser.lua:102 +"expected a condition after 'while'" -- ./candran/can-parser/parser.lua:102 }, -- ./candran/can-parser/parser.lua:102 { -- ./candran/can-parser/parser.lua:103 -"ErrExprRep", -- ./candran/can-parser/parser.lua:103 -"expected a conditions after 'until'" -- ./candran/can-parser/parser.lua:103 +"ErrDoWhile", -- ./candran/can-parser/parser.lua:103 +"expected 'do' after the condition" -- ./candran/can-parser/parser.lua:103 }, -- ./candran/can-parser/parser.lua:103 +{ -- ./candran/can-parser/parser.lua:104 +"ErrEndWhile", -- ./candran/can-parser/parser.lua:104 +"expected 'end' to close the while loop" -- ./candran/can-parser/parser.lua:104 +}, -- ./candran/can-parser/parser.lua:104 { -- ./candran/can-parser/parser.lua:105 -"ErrForRange", -- ./candran/can-parser/parser.lua:105 -"expected a numeric or generic range after 'for'" -- ./candran/can-parser/parser.lua:105 +"ErrUntilRep", -- ./candran/can-parser/parser.lua:105 +"expected 'until' at the end of the repeat loop" -- ./candran/can-parser/parser.lua:105 }, -- ./candran/can-parser/parser.lua:105 { -- ./candran/can-parser/parser.lua:106 -"ErrEndFor", -- ./candran/can-parser/parser.lua:106 -"expected 'end' to close the for loop" -- ./candran/can-parser/parser.lua:106 +"ErrExprRep", -- ./candran/can-parser/parser.lua:106 +"expected a conditions after 'until'" -- ./candran/can-parser/parser.lua:106 }, -- ./candran/can-parser/parser.lua:106 -{ -- ./candran/can-parser/parser.lua:107 -"ErrExprFor1", -- ./candran/can-parser/parser.lua:107 -"expected a starting expression for the numeric range" -- ./candran/can-parser/parser.lua:107 -}, -- ./candran/can-parser/parser.lua:107 { -- ./candran/can-parser/parser.lua:108 -"ErrCommaFor", -- ./candran/can-parser/parser.lua:108 -"expected ',' to split the start and end of the range" -- ./candran/can-parser/parser.lua:108 +"ErrForRange", -- ./candran/can-parser/parser.lua:108 +"expected a numeric or generic range after 'for'" -- ./candran/can-parser/parser.lua:108 }, -- ./candran/can-parser/parser.lua:108 { -- ./candran/can-parser/parser.lua:109 -"ErrExprFor2", -- ./candran/can-parser/parser.lua:109 -"expected an ending expression for the numeric range" -- ./candran/can-parser/parser.lua:109 +"ErrEndFor", -- ./candran/can-parser/parser.lua:109 +"expected 'end' to close the for loop" -- ./candran/can-parser/parser.lua:109 }, -- ./candran/can-parser/parser.lua:109 { -- ./candran/can-parser/parser.lua:110 -"ErrExprFor3", -- ./candran/can-parser/parser.lua:110 -"expected a step expression for the numeric range after ','" -- ./candran/can-parser/parser.lua:110 +"ErrExprFor1", -- ./candran/can-parser/parser.lua:110 +"expected a starting expression for the numeric range" -- ./candran/can-parser/parser.lua:110 }, -- ./candran/can-parser/parser.lua:110 { -- ./candran/can-parser/parser.lua:111 -"ErrInFor", -- ./candran/can-parser/parser.lua:111 -"expected '=' or 'in' after the variable(s)" -- ./candran/can-parser/parser.lua:111 +"ErrCommaFor", -- ./candran/can-parser/parser.lua:111 +"expected ',' to split the start and end of the range" -- ./candran/can-parser/parser.lua:111 }, -- ./candran/can-parser/parser.lua:111 { -- ./candran/can-parser/parser.lua:112 -"ErrEListFor", -- ./candran/can-parser/parser.lua:112 -"expected one or more expressions after 'in'" -- ./candran/can-parser/parser.lua:112 +"ErrExprFor2", -- ./candran/can-parser/parser.lua:112 +"expected an ending expression for the numeric range" -- ./candran/can-parser/parser.lua:112 }, -- ./candran/can-parser/parser.lua:112 { -- ./candran/can-parser/parser.lua:113 -"ErrDoFor", -- ./candran/can-parser/parser.lua:113 -"expected 'do' after the range of the for loop" -- ./candran/can-parser/parser.lua:113 +"ErrExprFor3", -- ./candran/can-parser/parser.lua:113 +"expected a step expression for the numeric range after ','" -- ./candran/can-parser/parser.lua:113 }, -- ./candran/can-parser/parser.lua:113 +{ -- ./candran/can-parser/parser.lua:114 +"ErrInFor", -- ./candran/can-parser/parser.lua:114 +"expected '=' or 'in' after the variable(s)" -- ./candran/can-parser/parser.lua:114 +}, -- ./candran/can-parser/parser.lua:114 { -- ./candran/can-parser/parser.lua:115 -"ErrDefLocal", -- ./candran/can-parser/parser.lua:115 -"expected a function definition or assignment after local" -- ./candran/can-parser/parser.lua:115 +"ErrEListFor", -- ./candran/can-parser/parser.lua:115 +"expected one or more expressions after 'in'" -- ./candran/can-parser/parser.lua:115 }, -- ./candran/can-parser/parser.lua:115 { -- ./candran/can-parser/parser.lua:116 -"ErrDefLet", -- ./candran/can-parser/parser.lua:116 -"expected an assignment after let" -- ./candran/can-parser/parser.lua:116 +"ErrDoFor", -- ./candran/can-parser/parser.lua:116 +"expected 'do' after the range of the for loop" -- ./candran/can-parser/parser.lua:116 }, -- ./candran/can-parser/parser.lua:116 -{ -- ./candran/can-parser/parser.lua:117 -"ErrDefClose", -- ./candran/can-parser/parser.lua:117 -"expected an assignment after close" -- ./candran/can-parser/parser.lua:117 -}, -- ./candran/can-parser/parser.lua:117 { -- ./candran/can-parser/parser.lua:118 -"ErrDefConst", -- ./candran/can-parser/parser.lua:118 -"expected an assignment after const" -- ./candran/can-parser/parser.lua:118 +"ErrDefGlobal", -- ./candran/can-parser/parser.lua:118 +"expected a function definition or assignment after global" -- ./candran/can-parser/parser.lua:118 }, -- ./candran/can-parser/parser.lua:118 { -- ./candran/can-parser/parser.lua:119 -"ErrNameLFunc", -- ./candran/can-parser/parser.lua:119 -"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:119 +"ErrDefLocal", -- ./candran/can-parser/parser.lua:119 +"expected a function definition or assignment after local" -- ./candran/can-parser/parser.lua:119 }, -- ./candran/can-parser/parser.lua:119 { -- ./candran/can-parser/parser.lua:120 -"ErrEListLAssign", -- ./candran/can-parser/parser.lua:120 -"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:120 +"ErrDefLet", -- ./candran/can-parser/parser.lua:120 +"expected an assignment after let" -- ./candran/can-parser/parser.lua:120 }, -- ./candran/can-parser/parser.lua:120 { -- ./candran/can-parser/parser.lua:121 -"ErrEListAssign", -- ./candran/can-parser/parser.lua:121 -"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:121 +"ErrDefClose", -- ./candran/can-parser/parser.lua:121 +"expected an assignment after close" -- ./candran/can-parser/parser.lua:121 }, -- ./candran/can-parser/parser.lua:121 +{ -- ./candran/can-parser/parser.lua:122 +"ErrDefConst", -- ./candran/can-parser/parser.lua:122 +"expected an assignment after const" -- ./candran/can-parser/parser.lua:122 +}, -- ./candran/can-parser/parser.lua:122 { -- ./candran/can-parser/parser.lua:123 -"ErrFuncName", -- ./candran/can-parser/parser.lua:123 +"ErrNameLFunc", -- ./candran/can-parser/parser.lua:123 "expected a function name after 'function'" -- ./candran/can-parser/parser.lua:123 }, -- ./candran/can-parser/parser.lua:123 { -- ./candran/can-parser/parser.lua:124 -"ErrNameFunc1", -- ./candran/can-parser/parser.lua:124 -"expected a function name after '.'" -- ./candran/can-parser/parser.lua:124 +"ErrEListLAssign", -- ./candran/can-parser/parser.lua:124 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:124 }, -- ./candran/can-parser/parser.lua:124 { -- ./candran/can-parser/parser.lua:125 -"ErrNameFunc2", -- ./candran/can-parser/parser.lua:125 -"expected a method name after ':'" -- ./candran/can-parser/parser.lua:125 +"ErrEListAssign", -- ./candran/can-parser/parser.lua:125 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:125 }, -- ./candran/can-parser/parser.lua:125 -{ -- ./candran/can-parser/parser.lua:126 -"ErrOParenPList", -- ./candran/can-parser/parser.lua:126 -"expected '(' for the parameter list" -- ./candran/can-parser/parser.lua:126 -}, -- ./candran/can-parser/parser.lua:126 { -- ./candran/can-parser/parser.lua:127 -"ErrCParenPList", -- ./candran/can-parser/parser.lua:127 -"expected ')' to close the parameter list" -- ./candran/can-parser/parser.lua:127 +"ErrFuncName", -- ./candran/can-parser/parser.lua:127 +"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:127 }, -- ./candran/can-parser/parser.lua:127 { -- ./candran/can-parser/parser.lua:128 -"ErrEndFunc", -- ./candran/can-parser/parser.lua:128 -"expected 'end' to close the function body" -- ./candran/can-parser/parser.lua:128 +"ErrNameFunc1", -- ./candran/can-parser/parser.lua:128 +"expected a function name after '.'" -- ./candran/can-parser/parser.lua:128 }, -- ./candran/can-parser/parser.lua:128 { -- ./candran/can-parser/parser.lua:129 -"ErrParList", -- ./candran/can-parser/parser.lua:129 -"expected a variable name or '...' after ','" -- ./candran/can-parser/parser.lua:129 +"ErrNameFunc2", -- ./candran/can-parser/parser.lua:129 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:129 }, -- ./candran/can-parser/parser.lua:129 +{ -- ./candran/can-parser/parser.lua:130 +"ErrOParenPList", -- ./candran/can-parser/parser.lua:130 +"expected '(' for the parameter list" -- ./candran/can-parser/parser.lua:130 +}, -- ./candran/can-parser/parser.lua:130 { -- ./candran/can-parser/parser.lua:131 -"ErrLabel", -- ./candran/can-parser/parser.lua:131 -"expected a label name after '::'" -- ./candran/can-parser/parser.lua:131 +"ErrCParenPList", -- ./candran/can-parser/parser.lua:131 +"expected ')' to close the parameter list" -- ./candran/can-parser/parser.lua:131 }, -- ./candran/can-parser/parser.lua:131 { -- ./candran/can-parser/parser.lua:132 -"ErrCloseLabel", -- ./candran/can-parser/parser.lua:132 -"expected '::' after the label" -- ./candran/can-parser/parser.lua:132 +"ErrEndFunc", -- ./candran/can-parser/parser.lua:132 +"expected 'end' to close the function body" -- ./candran/can-parser/parser.lua:132 }, -- ./candran/can-parser/parser.lua:132 { -- ./candran/can-parser/parser.lua:133 -"ErrGoto", -- ./candran/can-parser/parser.lua:133 -"expected a label after 'goto'" -- ./candran/can-parser/parser.lua:133 +"ErrParList", -- ./candran/can-parser/parser.lua:133 +"expected a variable name or '...' after ','" -- ./candran/can-parser/parser.lua:133 }, -- ./candran/can-parser/parser.lua:133 -{ -- ./candran/can-parser/parser.lua:134 -"ErrRetList", -- ./candran/can-parser/parser.lua:134 -"expected an expression after ',' in the return statement" -- ./candran/can-parser/parser.lua:134 -}, -- ./candran/can-parser/parser.lua:134 +{ -- ./candran/can-parser/parser.lua:135 +"ErrLabel", -- ./candran/can-parser/parser.lua:135 +"expected a label name after '::'" -- ./candran/can-parser/parser.lua:135 +}, -- ./candran/can-parser/parser.lua:135 { -- ./candran/can-parser/parser.lua:136 -"ErrVarList", -- ./candran/can-parser/parser.lua:136 -"expected a variable name after ','" -- ./candran/can-parser/parser.lua:136 +"ErrCloseLabel", -- ./candran/can-parser/parser.lua:136 +"expected '::' after the label" -- ./candran/can-parser/parser.lua:136 }, -- ./candran/can-parser/parser.lua:136 { -- ./candran/can-parser/parser.lua:137 -"ErrExprList", -- ./candran/can-parser/parser.lua:137 -"expected an expression after ','" -- ./candran/can-parser/parser.lua:137 +"ErrGoto", -- ./candran/can-parser/parser.lua:137 +"expected a label after 'goto'" -- ./candran/can-parser/parser.lua:137 }, -- ./candran/can-parser/parser.lua:137 -{ -- ./candran/can-parser/parser.lua:139 -"ErrOrExpr", -- ./candran/can-parser/parser.lua:139 -"expected an expression after 'or'" -- ./candran/can-parser/parser.lua:139 -}, -- ./candran/can-parser/parser.lua:139 +{ -- ./candran/can-parser/parser.lua:138 +"ErrRetList", -- ./candran/can-parser/parser.lua:138 +"expected an expression after ',' in the return statement" -- ./candran/can-parser/parser.lua:138 +}, -- ./candran/can-parser/parser.lua:138 { -- ./candran/can-parser/parser.lua:140 -"ErrAndExpr", -- ./candran/can-parser/parser.lua:140 -"expected an expression after 'and'" -- ./candran/can-parser/parser.lua:140 +"ErrVarList", -- ./candran/can-parser/parser.lua:140 +"expected a variable name after ','" -- ./candran/can-parser/parser.lua:140 }, -- ./candran/can-parser/parser.lua:140 { -- ./candran/can-parser/parser.lua:141 -"ErrRelExpr", -- ./candran/can-parser/parser.lua:141 -"expected an expression after the relational operator" -- ./candran/can-parser/parser.lua:141 +"ErrExprList", -- ./candran/can-parser/parser.lua:141 +"expected an expression after ','" -- ./candran/can-parser/parser.lua:141 }, -- ./candran/can-parser/parser.lua:141 -{ -- ./candran/can-parser/parser.lua:142 -"ErrBOrExpr", -- ./candran/can-parser/parser.lua:142 -"expected an expression after '|'" -- ./candran/can-parser/parser.lua:142 -}, -- ./candran/can-parser/parser.lua:142 { -- ./candran/can-parser/parser.lua:143 -"ErrBXorExpr", -- ./candran/can-parser/parser.lua:143 -"expected an expression after '~'" -- ./candran/can-parser/parser.lua:143 +"ErrOrExpr", -- ./candran/can-parser/parser.lua:143 +"expected an expression after 'or'" -- ./candran/can-parser/parser.lua:143 }, -- ./candran/can-parser/parser.lua:143 { -- ./candran/can-parser/parser.lua:144 -"ErrBAndExpr", -- ./candran/can-parser/parser.lua:144 -"expected an expression after '&'" -- ./candran/can-parser/parser.lua:144 +"ErrAndExpr", -- ./candran/can-parser/parser.lua:144 +"expected an expression after 'and'" -- ./candran/can-parser/parser.lua:144 }, -- ./candran/can-parser/parser.lua:144 { -- ./candran/can-parser/parser.lua:145 -"ErrShiftExpr", -- ./candran/can-parser/parser.lua:145 -"expected an expression after the bit shift" -- ./candran/can-parser/parser.lua:145 +"ErrRelExpr", -- ./candran/can-parser/parser.lua:145 +"expected an expression after the relational operator" -- ./candran/can-parser/parser.lua:145 }, -- ./candran/can-parser/parser.lua:145 { -- ./candran/can-parser/parser.lua:146 -"ErrConcatExpr", -- ./candran/can-parser/parser.lua:146 -"expected an expression after '..'" -- ./candran/can-parser/parser.lua:146 +"ErrBOrExpr", -- ./candran/can-parser/parser.lua:146 +"expected an expression after '|'" -- ./candran/can-parser/parser.lua:146 }, -- ./candran/can-parser/parser.lua:146 { -- ./candran/can-parser/parser.lua:147 -"ErrAddExpr", -- ./candran/can-parser/parser.lua:147 -"expected an expression after the additive operator" -- ./candran/can-parser/parser.lua:147 +"ErrBXorExpr", -- ./candran/can-parser/parser.lua:147 +"expected an expression after '~'" -- ./candran/can-parser/parser.lua:147 }, -- ./candran/can-parser/parser.lua:147 { -- ./candran/can-parser/parser.lua:148 -"ErrMulExpr", -- ./candran/can-parser/parser.lua:148 -"expected an expression after the multiplicative operator" -- ./candran/can-parser/parser.lua:148 +"ErrBAndExpr", -- ./candran/can-parser/parser.lua:148 +"expected an expression after '&'" -- ./candran/can-parser/parser.lua:148 }, -- ./candran/can-parser/parser.lua:148 { -- ./candran/can-parser/parser.lua:149 -"ErrUnaryExpr", -- ./candran/can-parser/parser.lua:149 -"expected an expression after the unary operator" -- ./candran/can-parser/parser.lua:149 +"ErrShiftExpr", -- ./candran/can-parser/parser.lua:149 +"expected an expression after the bit shift" -- ./candran/can-parser/parser.lua:149 }, -- ./candran/can-parser/parser.lua:149 { -- ./candran/can-parser/parser.lua:150 -"ErrPowExpr", -- ./candran/can-parser/parser.lua:150 -"expected an expression after '^'" -- ./candran/can-parser/parser.lua:150 +"ErrConcatExpr", -- ./candran/can-parser/parser.lua:150 +"expected an expression after '..'" -- ./candran/can-parser/parser.lua:150 }, -- ./candran/can-parser/parser.lua:150 +{ -- ./candran/can-parser/parser.lua:151 +"ErrAddExpr", -- ./candran/can-parser/parser.lua:151 +"expected an expression after the additive operator" -- ./candran/can-parser/parser.lua:151 +}, -- ./candran/can-parser/parser.lua:151 { -- ./candran/can-parser/parser.lua:152 -"ErrExprParen", -- ./candran/can-parser/parser.lua:152 -"expected an expression after '('" -- ./candran/can-parser/parser.lua:152 +"ErrMulExpr", -- ./candran/can-parser/parser.lua:152 +"expected an expression after the multiplicative operator" -- ./candran/can-parser/parser.lua:152 }, -- ./candran/can-parser/parser.lua:152 { -- ./candran/can-parser/parser.lua:153 -"ErrCParenExpr", -- ./candran/can-parser/parser.lua:153 -"expected ')' to close the expression" -- ./candran/can-parser/parser.lua:153 +"ErrUnaryExpr", -- ./candran/can-parser/parser.lua:153 +"expected an expression after the unary operator" -- ./candran/can-parser/parser.lua:153 }, -- ./candran/can-parser/parser.lua:153 { -- ./candran/can-parser/parser.lua:154 -"ErrNameIndex", -- ./candran/can-parser/parser.lua:154 -"expected a field name after '.'" -- ./candran/can-parser/parser.lua:154 +"ErrPowExpr", -- ./candran/can-parser/parser.lua:154 +"expected an expression after '^'" -- ./candran/can-parser/parser.lua:154 }, -- ./candran/can-parser/parser.lua:154 -{ -- ./candran/can-parser/parser.lua:155 -"ErrExprIndex", -- ./candran/can-parser/parser.lua:155 -"expected an expression after '['" -- ./candran/can-parser/parser.lua:155 -}, -- ./candran/can-parser/parser.lua:155 { -- ./candran/can-parser/parser.lua:156 -"ErrCBracketIndex", -- ./candran/can-parser/parser.lua:156 -"expected ']' to close the indexing expression" -- ./candran/can-parser/parser.lua:156 +"ErrExprParen", -- ./candran/can-parser/parser.lua:156 +"expected an expression after '('" -- ./candran/can-parser/parser.lua:156 }, -- ./candran/can-parser/parser.lua:156 { -- ./candran/can-parser/parser.lua:157 -"ErrNameMeth", -- ./candran/can-parser/parser.lua:157 -"expected a method name after ':'" -- ./candran/can-parser/parser.lua:157 +"ErrCParenExpr", -- ./candran/can-parser/parser.lua:157 +"expected ')' to close the expression" -- ./candran/can-parser/parser.lua:157 }, -- ./candran/can-parser/parser.lua:157 { -- ./candran/can-parser/parser.lua:158 -"ErrMethArgs", -- ./candran/can-parser/parser.lua:158 -"expected some arguments for the method call (or '()')" -- ./candran/can-parser/parser.lua:158 +"ErrNameIndex", -- ./candran/can-parser/parser.lua:158 +"expected a field name after '.'" -- ./candran/can-parser/parser.lua:158 }, -- ./candran/can-parser/parser.lua:158 +{ -- ./candran/can-parser/parser.lua:159 +"ErrExprIndex", -- ./candran/can-parser/parser.lua:159 +"expected an expression after '['" -- ./candran/can-parser/parser.lua:159 +}, -- ./candran/can-parser/parser.lua:159 { -- ./candran/can-parser/parser.lua:160 -"ErrArgList", -- ./candran/can-parser/parser.lua:160 -"expected an expression after ',' in the argument list" -- ./candran/can-parser/parser.lua:160 +"ErrCBracketIndex", -- ./candran/can-parser/parser.lua:160 +"expected ']' to close the indexing expression" -- ./candran/can-parser/parser.lua:160 }, -- ./candran/can-parser/parser.lua:160 { -- ./candran/can-parser/parser.lua:161 -"ErrCParenArgs", -- ./candran/can-parser/parser.lua:161 -"expected ')' to close the argument list" -- ./candran/can-parser/parser.lua:161 +"ErrNameMeth", -- ./candran/can-parser/parser.lua:161 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:161 }, -- ./candran/can-parser/parser.lua:161 -{ -- ./candran/can-parser/parser.lua:163 -"ErrCBraceTable", -- ./candran/can-parser/parser.lua:163 -"expected '}' to close the table constructor" -- ./candran/can-parser/parser.lua:163 -}, -- ./candran/can-parser/parser.lua:163 +{ -- ./candran/can-parser/parser.lua:162 +"ErrMethArgs", -- ./candran/can-parser/parser.lua:162 +"expected some arguments for the method call (or '()')" -- ./candran/can-parser/parser.lua:162 +}, -- ./candran/can-parser/parser.lua:162 { -- ./candran/can-parser/parser.lua:164 -"ErrEqField", -- ./candran/can-parser/parser.lua:164 -"expected '=' after the table key" -- ./candran/can-parser/parser.lua:164 +"ErrArgList", -- ./candran/can-parser/parser.lua:164 +"expected an expression after ',' in the argument list" -- ./candran/can-parser/parser.lua:164 }, -- ./candran/can-parser/parser.lua:164 { -- ./candran/can-parser/parser.lua:165 -"ErrExprField", -- ./candran/can-parser/parser.lua:165 -"expected an expression after '='" -- ./candran/can-parser/parser.lua:165 +"ErrCParenArgs", -- ./candran/can-parser/parser.lua:165 +"expected ')' to close the argument list" -- ./candran/can-parser/parser.lua:165 }, -- ./candran/can-parser/parser.lua:165 -{ -- ./candran/can-parser/parser.lua:166 -"ErrExprFKey", -- ./candran/can-parser/parser.lua:166 -"expected an expression after '[' for the table key" -- ./candran/can-parser/parser.lua:166 -}, -- ./candran/can-parser/parser.lua:166 { -- ./candran/can-parser/parser.lua:167 -"ErrCBracketFKey", -- ./candran/can-parser/parser.lua:167 -"expected ']' to close the table key" -- ./candran/can-parser/parser.lua:167 +"ErrCBraceTable", -- ./candran/can-parser/parser.lua:167 +"expected '}' to close the table constructor" -- ./candran/can-parser/parser.lua:167 }, -- ./candran/can-parser/parser.lua:167 +{ -- ./candran/can-parser/parser.lua:168 +"ErrEqField", -- ./candran/can-parser/parser.lua:168 +"expected '=' after the table key" -- ./candran/can-parser/parser.lua:168 +}, -- ./candran/can-parser/parser.lua:168 { -- ./candran/can-parser/parser.lua:169 -"ErrCBraceDestructuring", -- ./candran/can-parser/parser.lua:169 -"expected '}' to close the destructuring variable list" -- ./candran/can-parser/parser.lua:169 +"ErrExprField", -- ./candran/can-parser/parser.lua:169 +"expected an expression after '='" -- ./candran/can-parser/parser.lua:169 }, -- ./candran/can-parser/parser.lua:169 { -- ./candran/can-parser/parser.lua:170 -"ErrDestructuringEqField", -- ./candran/can-parser/parser.lua:170 -"expected '=' after the table key in destructuring variable list" -- ./candran/can-parser/parser.lua:170 +"ErrExprFKey", -- ./candran/can-parser/parser.lua:170 +"expected an expression after '[' for the table key" -- ./candran/can-parser/parser.lua:170 }, -- ./candran/can-parser/parser.lua:170 { -- ./candran/can-parser/parser.lua:171 -"ErrDestructuringExprField", -- ./candran/can-parser/parser.lua:171 -"expected an identifier after '=' in destructuring variable list" -- ./candran/can-parser/parser.lua:171 +"ErrCBracketFKey", -- ./candran/can-parser/parser.lua:171 +"expected ']' to close the table key" -- ./candran/can-parser/parser.lua:171 }, -- ./candran/can-parser/parser.lua:171 { -- ./candran/can-parser/parser.lua:173 -"ErrCBracketTableCompr", -- ./candran/can-parser/parser.lua:173 -"expected ']' to close the table comprehension" -- ./candran/can-parser/parser.lua:173 +"ErrCBraceDestructuring", -- ./candran/can-parser/parser.lua:173 +"expected '}' to close the destructuring variable list" -- ./candran/can-parser/parser.lua:173 }, -- ./candran/can-parser/parser.lua:173 +{ -- ./candran/can-parser/parser.lua:174 +"ErrDestructuringEqField", -- ./candran/can-parser/parser.lua:174 +"expected '=' after the table key in destructuring variable list" -- ./candran/can-parser/parser.lua:174 +}, -- ./candran/can-parser/parser.lua:174 { -- ./candran/can-parser/parser.lua:175 -"ErrDigitHex", -- ./candran/can-parser/parser.lua:175 -"expected one or more hexadecimal digits after '0x'" -- ./candran/can-parser/parser.lua:175 +"ErrDestructuringExprField", -- ./candran/can-parser/parser.lua:175 +"expected an identifier after '=' in destructuring variable list" -- ./candran/can-parser/parser.lua:175 }, -- ./candran/can-parser/parser.lua:175 -{ -- ./candran/can-parser/parser.lua:176 -"ErrDigitDeci", -- ./candran/can-parser/parser.lua:176 -"expected one or more digits after the decimal point" -- ./candran/can-parser/parser.lua:176 -}, -- ./candran/can-parser/parser.lua:176 { -- ./candran/can-parser/parser.lua:177 -"ErrDigitExpo", -- ./candran/can-parser/parser.lua:177 -"expected one or more digits for the exponent" -- ./candran/can-parser/parser.lua:177 +"ErrCBracketTableCompr", -- ./candran/can-parser/parser.lua:177 +"expected ']' to close the table comprehension" -- ./candran/can-parser/parser.lua:177 }, -- ./candran/can-parser/parser.lua:177 { -- ./candran/can-parser/parser.lua:179 -"ErrQuote", -- ./candran/can-parser/parser.lua:179 -"unclosed string" -- ./candran/can-parser/parser.lua:179 +"ErrDigitHex", -- ./candran/can-parser/parser.lua:179 +"expected one or more hexadecimal digits after '0x'" -- ./candran/can-parser/parser.lua:179 }, -- ./candran/can-parser/parser.lua:179 { -- ./candran/can-parser/parser.lua:180 -"ErrHexEsc", -- ./candran/can-parser/parser.lua:180 -"expected exactly two hexadecimal digits after '\\x'" -- ./candran/can-parser/parser.lua:180 +"ErrDigitDeci", -- ./candran/can-parser/parser.lua:180 +"expected one or more digits after the decimal point" -- ./candran/can-parser/parser.lua:180 }, -- ./candran/can-parser/parser.lua:180 { -- ./candran/can-parser/parser.lua:181 -"ErrOBraceUEsc", -- ./candran/can-parser/parser.lua:181 -"expected '{' after '\\u'" -- ./candran/can-parser/parser.lua:181 +"ErrDigitExpo", -- ./candran/can-parser/parser.lua:181 +"expected one or more digits for the exponent" -- ./candran/can-parser/parser.lua:181 }, -- ./candran/can-parser/parser.lua:181 -{ -- ./candran/can-parser/parser.lua:182 -"ErrDigitUEsc", -- ./candran/can-parser/parser.lua:182 -"expected one or more hexadecimal digits for the UTF-8 code point" -- ./candran/can-parser/parser.lua:182 -}, -- ./candran/can-parser/parser.lua:182 { -- ./candran/can-parser/parser.lua:183 -"ErrCBraceUEsc", -- ./candran/can-parser/parser.lua:183 -"expected '}' after the code point" -- ./candran/can-parser/parser.lua:183 +"ErrQuote", -- ./candran/can-parser/parser.lua:183 +"unclosed string" -- ./candran/can-parser/parser.lua:183 }, -- ./candran/can-parser/parser.lua:183 { -- ./candran/can-parser/parser.lua:184 -"ErrEscSeq", -- ./candran/can-parser/parser.lua:184 -"invalid escape sequence" -- ./candran/can-parser/parser.lua:184 +"ErrHexEsc", -- ./candran/can-parser/parser.lua:184 +"expected exactly two hexadecimal digits after '\\x'" -- ./candran/can-parser/parser.lua:184 }, -- ./candran/can-parser/parser.lua:184 { -- ./candran/can-parser/parser.lua:185 -"ErrCloseLStr", -- ./candran/can-parser/parser.lua:185 -"unclosed long string" -- ./candran/can-parser/parser.lua:185 +"ErrOBraceUEsc", -- ./candran/can-parser/parser.lua:185 +"expected '{' after '\\u'" -- ./candran/can-parser/parser.lua:185 }, -- ./candran/can-parser/parser.lua:185 +{ -- ./candran/can-parser/parser.lua:186 +"ErrDigitUEsc", -- ./candran/can-parser/parser.lua:186 +"expected one or more hexadecimal digits for the UTF-8 code point" -- ./candran/can-parser/parser.lua:186 +}, -- ./candran/can-parser/parser.lua:186 { -- ./candran/can-parser/parser.lua:187 -"ErrUnknownAttribute", -- ./candran/can-parser/parser.lua:187 -"unknown variable attribute" -- ./candran/can-parser/parser.lua:187 +"ErrCBraceUEsc", -- ./candran/can-parser/parser.lua:187 +"expected '}' after the code point" -- ./candran/can-parser/parser.lua:187 }, -- ./candran/can-parser/parser.lua:187 { -- ./candran/can-parser/parser.lua:188 -"ErrCBracketAttribute", -- ./candran/can-parser/parser.lua:188 -"expected '>' to close the variable attribute" -- ./candran/can-parser/parser.lua:188 -} -- ./candran/can-parser/parser.lua:188 -} -- ./candran/can-parser/parser.lua:188 -local function throw(label) -- ./candran/can-parser/parser.lua:191 -label = "Err" .. label -- ./candran/can-parser/parser.lua:192 -for i, labelinfo in ipairs(labels) do -- ./candran/can-parser/parser.lua:193 -if labelinfo[1] == label then -- ./candran/can-parser/parser.lua:194 -return T(i) -- ./candran/can-parser/parser.lua:195 -end -- ./candran/can-parser/parser.lua:195 -end -- ./candran/can-parser/parser.lua:195 -error("Label not found: " .. label) -- ./candran/can-parser/parser.lua:199 +"ErrEscSeq", -- ./candran/can-parser/parser.lua:188 +"invalid escape sequence" -- ./candran/can-parser/parser.lua:188 +}, -- ./candran/can-parser/parser.lua:188 +{ -- ./candran/can-parser/parser.lua:189 +"ErrCloseLStr", -- ./candran/can-parser/parser.lua:189 +"unclosed long string" -- ./candran/can-parser/parser.lua:189 +}, -- ./candran/can-parser/parser.lua:189 +{ -- ./candran/can-parser/parser.lua:191 +"ErrUnknownAttribute", -- ./candran/can-parser/parser.lua:191 +"unknown variable attribute" -- ./candran/can-parser/parser.lua:191 +}, -- ./candran/can-parser/parser.lua:191 +{ -- ./candran/can-parser/parser.lua:192 +"ErrCBracketAttribute", -- ./candran/can-parser/parser.lua:192 +"expected '>' to close the variable attribute" -- ./candran/can-parser/parser.lua:192 +} -- ./candran/can-parser/parser.lua:192 +} -- ./candran/can-parser/parser.lua:192 +local function throw(label) -- ./candran/can-parser/parser.lua:195 +label = "Err" .. label -- ./candran/can-parser/parser.lua:196 +for i, labelinfo in ipairs(labels) do -- ./candran/can-parser/parser.lua:197 +if labelinfo[1] == label then -- ./candran/can-parser/parser.lua:198 +return T(i) -- ./candran/can-parser/parser.lua:199 end -- ./candran/can-parser/parser.lua:199 -local function expect(patt, label) -- ./candran/can-parser/parser.lua:202 -return patt + throw(label) -- ./candran/can-parser/parser.lua:203 +end -- ./candran/can-parser/parser.lua:199 +error("Label not found: " .. label) -- ./candran/can-parser/parser.lua:203 end -- ./candran/can-parser/parser.lua:203 -local function token(patt) -- ./candran/can-parser/parser.lua:209 -return patt * V("Skip") -- ./candran/can-parser/parser.lua:210 -end -- ./candran/can-parser/parser.lua:210 -local function sym(str) -- ./candran/can-parser/parser.lua:213 -return token(P(str)) -- ./candran/can-parser/parser.lua:214 +local function expect(patt, label) -- ./candran/can-parser/parser.lua:206 +return patt + throw(label) -- ./candran/can-parser/parser.lua:207 +end -- ./candran/can-parser/parser.lua:207 +local function token(patt) -- ./candran/can-parser/parser.lua:213 +return patt * V("Skip") -- ./candran/can-parser/parser.lua:214 end -- ./candran/can-parser/parser.lua:214 -local function kw(str) -- ./candran/can-parser/parser.lua:217 -return token(P(str) * - V("IdRest")) -- ./candran/can-parser/parser.lua:218 +local function sym(str) -- ./candran/can-parser/parser.lua:217 +return token(P(str)) -- ./candran/can-parser/parser.lua:218 end -- ./candran/can-parser/parser.lua:218 -local function tagC(tag, patt) -- ./candran/can-parser/parser.lua:221 -return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./candran/can-parser/parser.lua:222 +local function kw(str) -- ./candran/can-parser/parser.lua:221 +return token(P(str) * - V("IdRest")) -- ./candran/can-parser/parser.lua:222 end -- ./candran/can-parser/parser.lua:222 -local function unaryOp(op, e) -- ./candran/can-parser/parser.lua:225 -return { -- ./candran/can-parser/parser.lua:226 -["tag"] = "Op", -- ./candran/can-parser/parser.lua:226 -["pos"] = e["pos"], -- ./candran/can-parser/parser.lua:226 -[1] = op, -- ./candran/can-parser/parser.lua:226 -[2] = e -- ./candran/can-parser/parser.lua:226 -} -- ./candran/can-parser/parser.lua:226 +local function tagC(tag, patt) -- ./candran/can-parser/parser.lua:225 +return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./candran/can-parser/parser.lua:226 end -- ./candran/can-parser/parser.lua:226 -local function binaryOp(e1, op, e2) -- ./candran/can-parser/parser.lua:229 -if not op then -- ./candran/can-parser/parser.lua:230 -return e1 -- ./candran/can-parser/parser.lua:231 -else -- ./candran/can-parser/parser.lua:231 -return { -- ./candran/can-parser/parser.lua:233 -["tag"] = "Op", -- ./candran/can-parser/parser.lua:233 -["pos"] = e1["pos"], -- ./candran/can-parser/parser.lua:233 -[1] = op, -- ./candran/can-parser/parser.lua:233 -[2] = e1, -- ./candran/can-parser/parser.lua:233 -[3] = e2 -- ./candran/can-parser/parser.lua:233 -} -- ./candran/can-parser/parser.lua:233 -end -- ./candran/can-parser/parser.lua:233 -end -- ./candran/can-parser/parser.lua:233 -local function sepBy(patt, sep, label) -- ./candran/can-parser/parser.lua:237 -if label then -- ./candran/can-parser/parser.lua:238 -return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./candran/can-parser/parser.lua:239 -else -- ./candran/can-parser/parser.lua:239 -return patt * Cg(sep * patt) ^ 0 -- ./candran/can-parser/parser.lua:241 -end -- ./candran/can-parser/parser.lua:241 -end -- ./candran/can-parser/parser.lua:241 -local function chainOp(patt, sep, label) -- ./candran/can-parser/parser.lua:245 -return Cf(sepBy(patt, sep, label), binaryOp) -- ./candran/can-parser/parser.lua:246 -end -- ./candran/can-parser/parser.lua:246 -local function commaSep(patt, label) -- ./candran/can-parser/parser.lua:249 -return sepBy(patt, sym(","), label) -- ./candran/can-parser/parser.lua:250 +local function unaryOp(op, e) -- ./candran/can-parser/parser.lua:229 +return { -- ./candran/can-parser/parser.lua:230 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:230 +["pos"] = e["pos"], -- ./candran/can-parser/parser.lua:230 +[1] = op, -- ./candran/can-parser/parser.lua:230 +[2] = e -- ./candran/can-parser/parser.lua:230 +} -- ./candran/can-parser/parser.lua:230 +end -- ./candran/can-parser/parser.lua:230 +local function binaryOp(e1, op, e2) -- ./candran/can-parser/parser.lua:233 +if not op then -- ./candran/can-parser/parser.lua:234 +return e1 -- ./candran/can-parser/parser.lua:235 +else -- ./candran/can-parser/parser.lua:235 +return { -- ./candran/can-parser/parser.lua:237 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:237 +["pos"] = e1["pos"], -- ./candran/can-parser/parser.lua:237 +[1] = op, -- ./candran/can-parser/parser.lua:237 +[2] = e1, -- ./candran/can-parser/parser.lua:237 +[3] = e2 -- ./candran/can-parser/parser.lua:237 +} -- ./candran/can-parser/parser.lua:237 +end -- ./candran/can-parser/parser.lua:237 +end -- ./candran/can-parser/parser.lua:237 +local function sepBy(patt, sep, label) -- ./candran/can-parser/parser.lua:241 +if label then -- ./candran/can-parser/parser.lua:242 +return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./candran/can-parser/parser.lua:243 +else -- ./candran/can-parser/parser.lua:243 +return patt * Cg(sep * patt) ^ 0 -- ./candran/can-parser/parser.lua:245 +end -- ./candran/can-parser/parser.lua:245 +end -- ./candran/can-parser/parser.lua:245 +local function chainOp(patt, sep, label) -- ./candran/can-parser/parser.lua:249 +return Cf(sepBy(patt, sep, label), binaryOp) -- ./candran/can-parser/parser.lua:250 end -- ./candran/can-parser/parser.lua:250 -local function tagDo(block) -- ./candran/can-parser/parser.lua:253 -block["tag"] = "Do" -- ./candran/can-parser/parser.lua:254 -return block -- ./candran/can-parser/parser.lua:255 -end -- ./candran/can-parser/parser.lua:255 -local function fixFuncStat(func) -- ./candran/can-parser/parser.lua:258 -if func[1]["is_method"] then -- ./candran/can-parser/parser.lua:259 -table["insert"](func[2][1], 1, { -- ./candran/can-parser/parser.lua:259 -["tag"] = "Id", -- ./candran/can-parser/parser.lua:259 -[1] = "self" -- ./candran/can-parser/parser.lua:259 -}) -- ./candran/can-parser/parser.lua:259 +local function commaSep(patt, label) -- ./candran/can-parser/parser.lua:253 +return sepBy(patt, sym(","), label) -- ./candran/can-parser/parser.lua:254 +end -- ./candran/can-parser/parser.lua:254 +local function tagDo(block) -- ./candran/can-parser/parser.lua:257 +block["tag"] = "Do" -- ./candran/can-parser/parser.lua:258 +return block -- ./candran/can-parser/parser.lua:259 end -- ./candran/can-parser/parser.lua:259 -func[1] = { func[1] } -- ./candran/can-parser/parser.lua:260 -func[2] = { func[2] } -- ./candran/can-parser/parser.lua:261 -return func -- ./candran/can-parser/parser.lua:262 -end -- ./candran/can-parser/parser.lua:262 -local function addDots(params, dots) -- ./candran/can-parser/parser.lua:265 -if dots then -- ./candran/can-parser/parser.lua:266 -table["insert"](params, dots) -- ./candran/can-parser/parser.lua:266 +local function fixFuncStat(func) -- ./candran/can-parser/parser.lua:262 +if func[1]["is_method"] then -- ./candran/can-parser/parser.lua:263 +table["insert"](func[2][1], 1, { -- ./candran/can-parser/parser.lua:263 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:263 +[1] = "self" -- ./candran/can-parser/parser.lua:263 +}) -- ./candran/can-parser/parser.lua:263 +end -- ./candran/can-parser/parser.lua:263 +func[1] = { func[1] } -- ./candran/can-parser/parser.lua:264 +func[2] = { func[2] } -- ./candran/can-parser/parser.lua:265 +return func -- ./candran/can-parser/parser.lua:266 end -- ./candran/can-parser/parser.lua:266 -return params -- ./candran/can-parser/parser.lua:267 -end -- ./candran/can-parser/parser.lua:267 -local function insertIndex(t, index) -- ./candran/can-parser/parser.lua:270 -return { -- ./candran/can-parser/parser.lua:271 -["tag"] = "Index", -- ./candran/can-parser/parser.lua:271 -["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:271 -[1] = t, -- ./candran/can-parser/parser.lua:271 -[2] = index -- ./candran/can-parser/parser.lua:271 -} -- ./candran/can-parser/parser.lua:271 +local function addDots(params, dots) -- ./candran/can-parser/parser.lua:269 +if dots then -- ./candran/can-parser/parser.lua:270 +table["insert"](params, dots) -- ./candran/can-parser/parser.lua:270 +end -- ./candran/can-parser/parser.lua:270 +return params -- ./candran/can-parser/parser.lua:271 end -- ./candran/can-parser/parser.lua:271 -local function markMethod(t, method) -- ./candran/can-parser/parser.lua:274 -if method then -- ./candran/can-parser/parser.lua:275 -return { -- ./candran/can-parser/parser.lua:276 -["tag"] = "Index", -- ./candran/can-parser/parser.lua:276 -["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:276 -["is_method"] = true, -- ./candran/can-parser/parser.lua:276 -[1] = t, -- ./candran/can-parser/parser.lua:276 -[2] = method -- ./candran/can-parser/parser.lua:276 -} -- ./candran/can-parser/parser.lua:276 -end -- ./candran/can-parser/parser.lua:276 -return t -- ./candran/can-parser/parser.lua:278 -end -- ./candran/can-parser/parser.lua:278 -local function makeSuffixedExpr(t1, t2) -- ./candran/can-parser/parser.lua:281 -if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./candran/can-parser/parser.lua:282 -local t = { -- ./candran/can-parser/parser.lua:283 -["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:283 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:283 -[1] = t1 -- ./candran/can-parser/parser.lua:283 -} -- ./candran/can-parser/parser.lua:283 -for k, v in ipairs(t2) do -- ./candran/can-parser/parser.lua:284 -table["insert"](t, v) -- ./candran/can-parser/parser.lua:285 -end -- ./candran/can-parser/parser.lua:285 -return t -- ./candran/can-parser/parser.lua:287 -elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./candran/can-parser/parser.lua:288 -return { -- ./candran/can-parser/parser.lua:289 -["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:289 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:289 -[1] = t1, -- ./candran/can-parser/parser.lua:289 -[2] = t2[1] -- ./candran/can-parser/parser.lua:289 -} -- ./candran/can-parser/parser.lua:289 -elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./candran/can-parser/parser.lua:290 -return { -- ./candran/can-parser/parser.lua:291 -["tag"] = "SafeIndex", -- ./candran/can-parser/parser.lua:291 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:291 -[1] = t1, -- ./candran/can-parser/parser.lua:291 -[2] = t2[1] -- ./candran/can-parser/parser.lua:291 -} -- ./candran/can-parser/parser.lua:291 -elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./candran/can-parser/parser.lua:292 +local function insertIndex(t, index) -- ./candran/can-parser/parser.lua:274 +return { -- ./candran/can-parser/parser.lua:275 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:275 +["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:275 +[1] = t, -- ./candran/can-parser/parser.lua:275 +[2] = index -- ./candran/can-parser/parser.lua:275 +} -- ./candran/can-parser/parser.lua:275 +end -- ./candran/can-parser/parser.lua:275 +local function markMethod(t, method) -- ./candran/can-parser/parser.lua:278 +if method then -- ./candran/can-parser/parser.lua:279 +return { -- ./candran/can-parser/parser.lua:280 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:280 +["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:280 +["is_method"] = true, -- ./candran/can-parser/parser.lua:280 +[1] = t, -- ./candran/can-parser/parser.lua:280 +[2] = method -- ./candran/can-parser/parser.lua:280 +} -- ./candran/can-parser/parser.lua:280 +end -- ./candran/can-parser/parser.lua:280 +return t -- ./candran/can-parser/parser.lua:282 +end -- ./candran/can-parser/parser.lua:282 +local function makeSuffixedExpr(t1, t2) -- ./candran/can-parser/parser.lua:285 +if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./candran/can-parser/parser.lua:286 +local t = { -- ./candran/can-parser/parser.lua:287 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:287 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:287 +[1] = t1 -- ./candran/can-parser/parser.lua:287 +} -- ./candran/can-parser/parser.lua:287 +for k, v in ipairs(t2) do -- ./candran/can-parser/parser.lua:288 +table["insert"](t, v) -- ./candran/can-parser/parser.lua:289 +end -- ./candran/can-parser/parser.lua:289 +return t -- ./candran/can-parser/parser.lua:291 +elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./candran/can-parser/parser.lua:292 return { -- ./candran/can-parser/parser.lua:293 -["tag"] = "Index", -- ./candran/can-parser/parser.lua:293 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:293 ["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:293 [1] = t1, -- ./candran/can-parser/parser.lua:293 [2] = t2[1] -- ./candran/can-parser/parser.lua:293 } -- ./candran/can-parser/parser.lua:293 -else -- ./candran/can-parser/parser.lua:293 -error("unexpected tag in suffixed expression") -- ./candran/can-parser/parser.lua:295 -end -- ./candran/can-parser/parser.lua:295 -end -- ./candran/can-parser/parser.lua:295 -local function fixShortFunc(t) -- ./candran/can-parser/parser.lua:299 -if t[1] == ":" then -- ./candran/can-parser/parser.lua:300 -table["insert"](t[2], 1, { -- ./candran/can-parser/parser.lua:301 -["tag"] = "Id", -- ./candran/can-parser/parser.lua:301 -"self" -- ./candran/can-parser/parser.lua:301 -}) -- ./candran/can-parser/parser.lua:301 -table["remove"](t, 1) -- ./candran/can-parser/parser.lua:302 -t["is_method"] = true -- ./candran/can-parser/parser.lua:303 -end -- ./candran/can-parser/parser.lua:303 -t["is_short"] = true -- ./candran/can-parser/parser.lua:305 -return t -- ./candran/can-parser/parser.lua:306 -end -- ./candran/can-parser/parser.lua:306 -local function markImplicit(t) -- ./candran/can-parser/parser.lua:309 -t["implicit"] = true -- ./candran/can-parser/parser.lua:310 -return t -- ./candran/can-parser/parser.lua:311 -end -- ./candran/can-parser/parser.lua:311 -local function statToExpr(t) -- ./candran/can-parser/parser.lua:314 -t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:315 -return t -- ./candran/can-parser/parser.lua:316 -end -- ./candran/can-parser/parser.lua:316 -local function fixStructure(t) -- ./candran/can-parser/parser.lua:319 -local i = 1 -- ./candran/can-parser/parser.lua:320 -while i <= # t do -- ./candran/can-parser/parser.lua:321 -if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:322 -fixStructure(t[i]) -- ./candran/can-parser/parser.lua:323 -for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:324 -local stat = t[i][j] -- ./candran/can-parser/parser.lua:325 -if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:326 -table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:327 -table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:328 -if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:329 -stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:330 -end -- ./candran/can-parser/parser.lua:330 -end -- ./candran/can-parser/parser.lua:330 -end -- ./candran/can-parser/parser.lua:330 -end -- ./candran/can-parser/parser.lua:330 -i = i + 1 -- ./candran/can-parser/parser.lua:335 -end -- ./candran/can-parser/parser.lua:335 -return t -- ./candran/can-parser/parser.lua:337 -end -- ./candran/can-parser/parser.lua:337 -local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:340 -for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:341 -if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:343 -local exprlist -- ./candran/can-parser/parser.lua:344 -if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:346 -exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:347 -elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:348 -exprlist = stat -- ./candran/can-parser/parser.lua:349 -end -- ./candran/can-parser/parser.lua:349 -local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:352 -if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:356 -local p = i -- ./candran/can-parser/parser.lua:357 -for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:358 -p = i + j -- ./candran/can-parser/parser.lua:359 -table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:360 -if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:362 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:363 -end -- ./candran/can-parser/parser.lua:363 -if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:366 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:367 +elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./candran/can-parser/parser.lua:294 +return { -- ./candran/can-parser/parser.lua:295 +["tag"] = "SafeIndex", -- ./candran/can-parser/parser.lua:295 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:295 +[1] = t1, -- ./candran/can-parser/parser.lua:295 +[2] = t2[1] -- ./candran/can-parser/parser.lua:295 +} -- ./candran/can-parser/parser.lua:295 +elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./candran/can-parser/parser.lua:296 +return { -- ./candran/can-parser/parser.lua:297 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:297 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:297 +[1] = t1, -- ./candran/can-parser/parser.lua:297 +[2] = t2[1] -- ./candran/can-parser/parser.lua:297 +} -- ./candran/can-parser/parser.lua:297 +else -- ./candran/can-parser/parser.lua:297 +error("unexpected tag in suffixed expression") -- ./candran/can-parser/parser.lua:299 +end -- ./candran/can-parser/parser.lua:299 +end -- ./candran/can-parser/parser.lua:299 +local function fixShortFunc(t) -- ./candran/can-parser/parser.lua:303 +if t[1] == ":" then -- ./candran/can-parser/parser.lua:304 +table["insert"](t[2], 1, { -- ./candran/can-parser/parser.lua:305 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:305 +"self" -- ./candran/can-parser/parser.lua:305 +}) -- ./candran/can-parser/parser.lua:305 +table["remove"](t, 1) -- ./candran/can-parser/parser.lua:306 +t["is_method"] = true -- ./candran/can-parser/parser.lua:307 +end -- ./candran/can-parser/parser.lua:307 +t["is_short"] = true -- ./candran/can-parser/parser.lua:309 +return t -- ./candran/can-parser/parser.lua:310 +end -- ./candran/can-parser/parser.lua:310 +local function markImplicit(t) -- ./candran/can-parser/parser.lua:313 +t["implicit"] = true -- ./candran/can-parser/parser.lua:314 +return t -- ./candran/can-parser/parser.lua:315 +end -- ./candran/can-parser/parser.lua:315 +local function statToExpr(t) -- ./candran/can-parser/parser.lua:318 +t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:319 +return t -- ./candran/can-parser/parser.lua:320 +end -- ./candran/can-parser/parser.lua:320 +local function fixStructure(t) -- ./candran/can-parser/parser.lua:323 +local i = 1 -- ./candran/can-parser/parser.lua:324 +while i <= # t do -- ./candran/can-parser/parser.lua:325 +if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:326 +fixStructure(t[i]) -- ./candran/can-parser/parser.lua:327 +for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:328 +local stat = t[i][j] -- ./candran/can-parser/parser.lua:329 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:330 +table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:331 +table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:332 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:333 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:334 +end -- ./candran/can-parser/parser.lua:334 +end -- ./candran/can-parser/parser.lua:334 +end -- ./candran/can-parser/parser.lua:334 +end -- ./candran/can-parser/parser.lua:334 +i = i + 1 -- ./candran/can-parser/parser.lua:339 +end -- ./candran/can-parser/parser.lua:339 +return t -- ./candran/can-parser/parser.lua:341 +end -- ./candran/can-parser/parser.lua:341 +local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:344 +for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:345 +if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" or stat["tag"] == "Global" or stat["tag"] == "Globalrec" then -- ./candran/can-parser/parser.lua:347 +local exprlist -- ./candran/can-parser/parser.lua:348 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" or stat["tag"] == "Global" or stat["tag"] == "Globalrec" then -- ./candran/can-parser/parser.lua:350 +exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:351 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:352 +exprlist = stat -- ./candran/can-parser/parser.lua:353 +end -- ./candran/can-parser/parser.lua:353 +local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:356 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:360 +local p = i -- ./candran/can-parser/parser.lua:361 +for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:362 +p = i + j -- ./candran/can-parser/parser.lua:363 +table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:364 +if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:366 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:367 end -- ./candran/can-parser/parser.lua:367 -end -- ./candran/can-parser/parser.lua:367 -exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:371 -exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:372 -if not isRecCall then -- ./candran/can-parser/parser.lua:374 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:375 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:376 -end -- ./candran/can-parser/parser.lua:376 -end -- ./candran/can-parser/parser.lua:376 -return block, i -- ./candran/can-parser/parser.lua:380 -elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:383 -local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:384 -if r then -- ./candran/can-parser/parser.lua:385 -for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:386 -table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:387 -end -- ./candran/can-parser/parser.lua:387 -return block, i -- ./candran/can-parser/parser.lua:389 -end -- ./candran/can-parser/parser.lua:389 -elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:391 -local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:392 -if r then -- ./candran/can-parser/parser.lua:393 -return block, i -- ./candran/can-parser/parser.lua:394 -end -- ./candran/can-parser/parser.lua:394 -end -- ./candran/can-parser/parser.lua:394 -elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:399 -local blocks -- ./candran/can-parser/parser.lua:400 -if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:402 -blocks = stat -- ./candran/can-parser/parser.lua:403 -elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:404 -blocks = { stat } -- ./candran/can-parser/parser.lua:405 -end -- ./candran/can-parser/parser.lua:405 -for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:408 -if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:409 -local oldLen = # iblock -- ./candran/can-parser/parser.lua:410 -local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:411 -if newiBlock then -- ./candran/can-parser/parser.lua:412 -local p = i -- ./candran/can-parser/parser.lua:413 -for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:414 -p = p + 1 -- ./candran/can-parser/parser.lua:415 -table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:416 -iblock[j] = nil -- ./candran/can-parser/parser.lua:417 -end -- ./candran/can-parser/parser.lua:417 -if not isRecCall then -- ./candran/can-parser/parser.lua:420 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:421 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:422 -end -- ./candran/can-parser/parser.lua:422 -end -- ./candran/can-parser/parser.lua:422 -return block, i -- ./candran/can-parser/parser.lua:426 +if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:370 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:371 +end -- ./candran/can-parser/parser.lua:371 +end -- ./candran/can-parser/parser.lua:371 +exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:375 +exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:376 +if not isRecCall then -- ./candran/can-parser/parser.lua:378 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:379 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:380 +end -- ./candran/can-parser/parser.lua:380 +end -- ./candran/can-parser/parser.lua:380 +return block, i -- ./candran/can-parser/parser.lua:384 +elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:387 +local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:388 +if r then -- ./candran/can-parser/parser.lua:389 +for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:390 +table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:391 +end -- ./candran/can-parser/parser.lua:391 +return block, i -- ./candran/can-parser/parser.lua:393 +end -- ./candran/can-parser/parser.lua:393 +elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:395 +local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:396 +if r then -- ./candran/can-parser/parser.lua:397 +return block, i -- ./candran/can-parser/parser.lua:398 +end -- ./candran/can-parser/parser.lua:398 +end -- ./candran/can-parser/parser.lua:398 +elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:403 +local blocks -- ./candran/can-parser/parser.lua:404 +if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:406 +blocks = stat -- ./candran/can-parser/parser.lua:407 +elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:408 +blocks = { stat } -- ./candran/can-parser/parser.lua:409 +end -- ./candran/can-parser/parser.lua:409 +for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:412 +if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:413 +local oldLen = # iblock -- ./candran/can-parser/parser.lua:414 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:415 +if newiBlock then -- ./candran/can-parser/parser.lua:416 +local p = i -- ./candran/can-parser/parser.lua:417 +for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:418 +p = p + 1 -- ./candran/can-parser/parser.lua:419 +table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:420 +iblock[j] = nil -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +if not isRecCall then -- ./candran/can-parser/parser.lua:424 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:425 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:426 end -- ./candran/can-parser/parser.lua:426 end -- ./candran/can-parser/parser.lua:426 -end -- ./candran/can-parser/parser.lua:426 -end -- ./candran/can-parser/parser.lua:426 -end -- ./candran/can-parser/parser.lua:426 -return nil -- ./candran/can-parser/parser.lua:432 -end -- ./candran/can-parser/parser.lua:432 -local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:435 -local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:436 -if not r then -- ./candran/can-parser/parser.lua:437 -return false -- ./candran/can-parser/parser.lua:438 -end -- ./candran/can-parser/parser.lua:438 -return true, r -- ./candran/can-parser/parser.lua:440 -end -- ./candran/can-parser/parser.lua:440 -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:443 -if canFollow then -- ./candran/can-parser/parser.lua:444 -return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:447 -else -- ./candran/can-parser/parser.lua:447 -return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:451 -end -- ./candran/can-parser/parser.lua:451 -end -- ./candran/can-parser/parser.lua:451 -local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:455 -return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:457 -end -- ./candran/can-parser/parser.lua:457 -local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:460 -return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:462 -end -- ./candran/can-parser/parser.lua:462 -local function maybe(patt) -- ./candran/can-parser/parser.lua:465 -return # patt / 0 * patt -- ./candran/can-parser/parser.lua:466 +return block, i -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +return nil -- ./candran/can-parser/parser.lua:436 +end -- ./candran/can-parser/parser.lua:436 +local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:439 +local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:440 +if not r then -- ./candran/can-parser/parser.lua:441 +return false -- ./candran/can-parser/parser.lua:442 +end -- ./candran/can-parser/parser.lua:442 +return true, r -- ./candran/can-parser/parser.lua:444 +end -- ./candran/can-parser/parser.lua:444 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:447 +if canFollow then -- ./candran/can-parser/parser.lua:448 +return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:451 +else -- ./candran/can-parser/parser.lua:451 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:455 +end -- ./candran/can-parser/parser.lua:455 +end -- ./candran/can-parser/parser.lua:455 +local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:459 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:461 +end -- ./candran/can-parser/parser.lua:461 +local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:464 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:466 end -- ./candran/can-parser/parser.lua:466 -local function setAttribute(attribute) -- ./candran/can-parser/parser.lua:469 -return function(assign) -- ./candran/can-parser/parser.lua:470 -assign[1]["tag"] = "AttributeNameList" -- ./candran/can-parser/parser.lua:471 -for _, id in ipairs(assign[1]) do -- ./candran/can-parser/parser.lua:472 -if id["tag"] == "Id" then -- ./candran/can-parser/parser.lua:473 -id["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:474 -id[2] = attribute -- ./candran/can-parser/parser.lua:475 -elseif id["tag"] == "DestructuringId" then -- ./candran/can-parser/parser.lua:476 -for _, did in ipairs(id) do -- ./candran/can-parser/parser.lua:477 -did["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:478 -did[2] = attribute -- ./candran/can-parser/parser.lua:479 -end -- ./candran/can-parser/parser.lua:479 -end -- ./candran/can-parser/parser.lua:479 -end -- ./candran/can-parser/parser.lua:479 -return assign -- ./candran/can-parser/parser.lua:483 +local function maybe(patt) -- ./candran/can-parser/parser.lua:469 +return # patt / 0 * patt -- ./candran/can-parser/parser.lua:470 +end -- ./candran/can-parser/parser.lua:470 +local function setAttribute(attribute) -- ./candran/can-parser/parser.lua:473 +return function(assign) -- ./candran/can-parser/parser.lua:474 +assign[1]["tag"] = "AttributeNameList" -- ./candran/can-parser/parser.lua:475 +for _, id in ipairs(assign[1]) do -- ./candran/can-parser/parser.lua:476 +if id["tag"] == "Id" then -- ./candran/can-parser/parser.lua:477 +id["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:478 +id[2] = attribute -- ./candran/can-parser/parser.lua:479 +elseif id["tag"] == "DestructuringId" then -- ./candran/can-parser/parser.lua:480 +for _, did in ipairs(id) do -- ./candran/can-parser/parser.lua:481 +did["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:482 +did[2] = attribute -- ./candran/can-parser/parser.lua:483 end -- ./candran/can-parser/parser.lua:483 end -- ./candran/can-parser/parser.lua:483 -local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:488 -local function push(f) -- ./candran/can-parser/parser.lua:490 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:491 -table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:492 -return true -- ./candran/can-parser/parser.lua:493 -end) -- ./candran/can-parser/parser.lua:493 -end -- ./candran/can-parser/parser.lua:493 -local function pop(f) -- ./candran/can-parser/parser.lua:496 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:497 -table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:498 -return true -- ./candran/can-parser/parser.lua:499 -end) -- ./candran/can-parser/parser.lua:499 -end -- ./candran/can-parser/parser.lua:499 -local function when(f) -- ./candran/can-parser/parser.lua:502 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:503 -return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:504 -end) -- ./candran/can-parser/parser.lua:504 -end -- ./candran/can-parser/parser.lua:504 -local function set(f, patt) -- ./candran/can-parser/parser.lua:507 -return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:508 +end -- ./candran/can-parser/parser.lua:483 +return assign -- ./candran/can-parser/parser.lua:487 +end -- ./candran/can-parser/parser.lua:487 +end -- ./candran/can-parser/parser.lua:487 +local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:492 +local function push(f) -- ./candran/can-parser/parser.lua:494 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:495 +table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:496 +return true -- ./candran/can-parser/parser.lua:497 +end) -- ./candran/can-parser/parser.lua:497 +end -- ./candran/can-parser/parser.lua:497 +local function pop(f) -- ./candran/can-parser/parser.lua:500 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:501 +table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:502 +return true -- ./candran/can-parser/parser.lua:503 +end) -- ./candran/can-parser/parser.lua:503 +end -- ./candran/can-parser/parser.lua:503 +local function when(f) -- ./candran/can-parser/parser.lua:506 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:507 +return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:508 +end) -- ./candran/can-parser/parser.lua:508 end -- ./candran/can-parser/parser.lua:508 -local G = { -- ./candran/can-parser/parser.lua:512 -V("Lua"), -- ./candran/can-parser/parser.lua:512 -["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:513 +local function set(f, patt) -- ./candran/can-parser/parser.lua:511 +return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:512 +end -- ./candran/can-parser/parser.lua:512 +local G = { -- ./candran/can-parser/parser.lua:516 +V("Lua"), -- ./candran/can-parser/parser.lua:516 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:517 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:514 -["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:516 -["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("ConstStat") + V("CloseStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:522 -["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:523 -["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:525 -t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:525 -return t -- ./candran/can-parser/parser.lua:525 -end, -- ./candran/can-parser/parser.lua:525 -["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:526 -["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:528 -["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:529 -["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:530 -["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:531 -["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:533 -["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:534 -["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:535 -["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:536 -["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:538 -["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:539 -["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:541 -["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:542 -["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:543 -["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:545 -["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:546 -["LocalAssign"] = tagC("Local", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:548 -["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:550 -["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:552 -["ConstStat"] = kw("const") * expect(V("AttributeAssign") / setAttribute("const"), "DefConst"), -- ./candran/can-parser/parser.lua:554 -["CloseStat"] = kw("close") * expect(V("AttributeAssign") / setAttribute("close"), "DefClose"), -- ./candran/can-parser/parser.lua:555 -["AttributeAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:557 -["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:559 -["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:561 -["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:563 -["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:564 -["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:565 -["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:568 -["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:570 -["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:571 -["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:573 -["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:575 -["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:576 -["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:578 -["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:579 -["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:580 -["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:581 -["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:582 -["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:584 -["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")) / markImplicit, -- ./candran/can-parser/parser.lua:585 -["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:587 -["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:588 -["AttributeNameList"] = tagC("AttributeNameList", commaSep(V("AttributeId"))), -- ./candran/can-parser/parser.lua:589 -["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:590 -["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:591 -["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:593 -["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:594 -["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:596 -["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:598 -["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:599 -["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:600 -["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:601 -["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:602 -["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:603 -["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:604 -["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:605 -["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:606 -["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:607 -["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:608 -["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:610 -["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:611 -["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:621 -["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:623 -["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:625 -return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:625 -end), -- ./candran/can-parser/parser.lua:625 -["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:626 -return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:626 -end), -- ./candran/can-parser/parser.lua:626 -["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:630 -["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:633 -["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:634 -["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:638 -["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:640 -["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:642 -["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:643 -["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:644 -["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:646 -["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:649 -["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:651 -["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:652 -["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:654 -["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:656 -["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:657 -["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:659 -["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:661 -["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:662 -["AttributeSelfId"] = tagC("AttributeId", sym("@") / "self" * V("Attribute") ^ - 1), -- ./candran/can-parser/parser.lua:663 -["AttributeId"] = tagC("AttributeId", V("Name") * V("Attribute") ^ - 1) + V("AttributeSelfId"), -- ./candran/can-parser/parser.lua:664 -["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:665 -["Attribute"] = sym("<") * expect(kw("const") / "const" + kw("close") / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"), -- ./candran/can-parser/parser.lua:667 -["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:670 -["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:671 -["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:672 -return -- ./candran/can-parser/parser.lua:672 +")) ^ 0, -- ./candran/can-parser/parser.lua:518 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:520 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("GlobalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("ConstStat") + V("CloseStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:526 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:527 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:529 +t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:529 +return t -- ./candran/can-parser/parser.lua:529 +end, -- ./candran/can-parser/parser.lua:529 +["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:530 +["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:532 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:533 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:534 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:535 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:537 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:538 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:539 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:540 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:542 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:543 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:545 +["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:546 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:547 +["GlobalStat"] = kw("global") * expect(V("GlobalFunc") + V("GlobalAssign"), "DefGlobal"), -- ./candran/can-parser/parser.lua:549 +["GlobalFunc"] = tagC("Globalrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:550 +["GlobalAssign"] = tagC("Global", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Global", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")) + tagC("GlobalAll", V("Attribute") ^ - 1 * sym("*")), -- ./candran/can-parser/parser.lua:553 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:555 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:556 +["LocalAssign"] = tagC("Local", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:558 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:560 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:562 +["ConstStat"] = kw("const") * expect(V("LocalAssignNoAttribute") / setAttribute("const"), "DefConst"), -- ./candran/can-parser/parser.lua:564 +["CloseStat"] = kw("close") * expect(V("LocalAssignNoAttribute") / setAttribute("close"), "DefClose"), -- ./candran/can-parser/parser.lua:565 +["LocalAssignNoAttribute"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:567 +["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:569 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:571 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:573 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:574 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:575 +["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("ParDots", sym("...") * V("Id") ^ - 1), "ParList")) ^ - 1 / addDots + Ct(tagC("ParDots", sym("...") * V("Id") ^ - 1)) + Ct(Cc()), -- ./candran/can-parser/parser.lua:578 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:580 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:581 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:583 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:585 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:586 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:588 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:589 +["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:590 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:591 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:592 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:594 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")) / markImplicit, -- ./candran/can-parser/parser.lua:595 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:597 +["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:598 +["AttributeNameList"] = tagC("AttributeNameList", commaSep(V("AttributeId"))) + tagC("PrefixedAttributeNameList", V("Attribute") * commaSep(V("AttributeId"))), -- ./candran/can-parser/parser.lua:600 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:601 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:602 +["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:604 +["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:605 +["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:607 +["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:609 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:610 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:611 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:612 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:613 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:614 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:615 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:616 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:617 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:618 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:619 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:621 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:622 +["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:632 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:634 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:636 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:636 +end), -- ./candran/can-parser/parser.lua:636 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:637 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:637 +end), -- ./candran/can-parser/parser.lua:637 +["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:641 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:644 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:645 +["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:649 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:651 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:653 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:654 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:655 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:657 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:660 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:662 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:663 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:665 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:667 +["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:668 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:670 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:672 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:673 +["AttributeSelfId"] = tagC("AttributeId", sym("@") / "self" * V("Attribute") ^ - 1), -- ./candran/can-parser/parser.lua:674 +["AttributeId"] = tagC("AttributeId", V("Name") * V("Attribute") ^ - 1) + V("AttributeSelfId"), -- ./candran/can-parser/parser.lua:675 +["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:676 +["Attribute"] = sym("<") * expect(kw("const") / "const" + kw("close") / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"), -- ./candran/can-parser/parser.lua:678 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:681 +["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:682 +["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:683 +return -- ./candran/can-parser/parser.lua:683 end + P("--") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:673 -["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:675 -["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:676 -["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:680 -["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:681 -["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:682 -["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:683 -["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:685 -["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:686 -["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:688 -["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:690 -["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:691 -["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:692 -["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:693 -["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:694 -["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:696 +")) ^ 0, -- ./candran/can-parser/parser.lua:684 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:686 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:687 +["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "global" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:691 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:692 +["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:693 +["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:694 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:696 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:697 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:699 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:701 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:702 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:703 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:704 +["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:705 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:707 ["ShortStr"] = P("\"") * Cs((V("EscSeq") + (P(1) - S("\"\ "))) ^ 0) * expect(P("\""), "Quote") + P("'") * Cs((V("EscSeq") + (P(1) - S("'\ -"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:698 +"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:709 ["EscSeq"] = P("\\") / "" * (P("a") / "\7" + P("b") / "\8" + P("f") / "\12" + P("n") / "\ " + P("r") / "\13" + P("t") / "\9" + P("v") / "\11" + P("\ ") / "\ " + P("\13") / "\ -" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:728 -["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:731 -return s -- ./candran/can-parser/parser.lua:731 -end, -- ./candran/can-parser/parser.lua:731 +" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:739 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:742 +return s -- ./candran/can-parser/parser.lua:742 +end, -- ./candran/can-parser/parser.lua:742 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 1, -- ./candran/can-parser/parser.lua:732 -["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:733 -["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:734 -["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:735 -return # openEq == # closeEq -- ./candran/can-parser/parser.lua:735 -end), -- ./candran/can-parser/parser.lua:735 -["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:737 -["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:738 -["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:744 -["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:745 -["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:746 -["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:747 -["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:749 -["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:750 -["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:752 -["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:756 -["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:760 -["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:761 -["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:762 -} -- ./candran/can-parser/parser.lua:762 -local macroidentifier = { -- ./candran/can-parser/parser.lua:766 -expect(V("MacroIdentifier"), "InvalidStat") * expect(P(- 1), "Extra"), -- ./candran/can-parser/parser.lua:767 -["MacroIdentifier"] = tagC("MacroFunction", V("Id") * sym("(") * V("MacroFunctionArgs") * expect(sym(")"), "CParenPList")) + V("Id"), -- ./candran/can-parser/parser.lua:770 -["MacroFunctionArgs"] = V("NameList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()) -- ./candran/can-parser/parser.lua:774 -} -- ./candran/can-parser/parser.lua:774 -for k, v in pairs(G) do -- ./candran/can-parser/parser.lua:777 -if macroidentifier[k] == nil then -- ./candran/can-parser/parser.lua:777 -macroidentifier[k] = v -- ./candran/can-parser/parser.lua:777 -end -- ./candran/can-parser/parser.lua:777 -end -- ./candran/can-parser/parser.lua:777 -local parser = {} -- ./candran/can-parser/parser.lua:779 -local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:781 -local validate = validator["validate"] -- ./candran/can-parser/parser.lua:782 -local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:783 -parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:785 -local errorinfo = { -- ./candran/can-parser/parser.lua:786 -["subject"] = subject, -- ./candran/can-parser/parser.lua:786 -["filename"] = filename -- ./candran/can-parser/parser.lua:786 -} -- ./candran/can-parser/parser.lua:786 -lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:787 -local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:788 -if not ast then -- ./candran/can-parser/parser.lua:789 -local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:790 -return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:791 -end -- ./candran/can-parser/parser.lua:791 -return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:793 -end -- ./candran/can-parser/parser.lua:793 -parser["parsemacroidentifier"] = function(subject, filename) -- ./candran/can-parser/parser.lua:796 +") ^ - 1, -- ./candran/can-parser/parser.lua:743 +["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:744 +["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:745 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:746 +return # openEq == # closeEq -- ./candran/can-parser/parser.lua:746 +end), -- ./candran/can-parser/parser.lua:746 +["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:748 +["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:749 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:755 +["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:756 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:757 +["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:758 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:760 +["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:761 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:763 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:767 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:771 +["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:772 +["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:773 +} -- ./candran/can-parser/parser.lua:773 +local macroidentifier = { -- ./candran/can-parser/parser.lua:777 +expect(V("MacroIdentifier"), "InvalidStat") * expect(P(- 1), "Extra"), -- ./candran/can-parser/parser.lua:778 +["MacroIdentifier"] = tagC("MacroFunction", V("Id") * sym("(") * V("MacroFunctionArgs") * expect(sym(")"), "CParenPList")) + V("Id"), -- ./candran/can-parser/parser.lua:781 +["MacroFunctionArgs"] = V("NameList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()) -- ./candran/can-parser/parser.lua:785 +} -- ./candran/can-parser/parser.lua:785 +for k, v in pairs(G) do -- ./candran/can-parser/parser.lua:788 +if macroidentifier[k] == nil then -- ./candran/can-parser/parser.lua:788 +macroidentifier[k] = v -- ./candran/can-parser/parser.lua:788 +end -- ./candran/can-parser/parser.lua:788 +end -- ./candran/can-parser/parser.lua:788 +local parser = {} -- ./candran/can-parser/parser.lua:790 +local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:792 +local validate = validator["validate"] -- ./candran/can-parser/parser.lua:793 +local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:794 +parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:796 local errorinfo = { -- ./candran/can-parser/parser.lua:797 ["subject"] = subject, -- ./candran/can-parser/parser.lua:797 ["filename"] = filename -- ./candran/can-parser/parser.lua:797 } -- ./candran/can-parser/parser.lua:797 lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:798 -local ast, label, errpos = lpeg["match"](macroidentifier, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:799 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:799 if not ast then -- ./candran/can-parser/parser.lua:800 local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:801 return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:802 end -- ./candran/can-parser/parser.lua:802 -return ast -- ./candran/can-parser/parser.lua:804 +return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:804 end -- ./candran/can-parser/parser.lua:804 -return parser -- ./candran/can-parser/parser.lua:807 -end -- ./candran/can-parser/parser.lua:807 -local parser = _() or parser -- ./candran/can-parser/parser.lua:811 -package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:812 -local unpack = unpack or table["unpack"] -- candran.can:20 -candran["default"] = { -- candran.can:23 -["target"] = "lua54", -- candran.can:24 -["indentation"] = "", -- candran.can:25 +parser["parsemacroidentifier"] = function(subject, filename) -- ./candran/can-parser/parser.lua:807 +local errorinfo = { -- ./candran/can-parser/parser.lua:808 +["subject"] = subject, -- ./candran/can-parser/parser.lua:808 +["filename"] = filename -- ./candran/can-parser/parser.lua:808 +} -- ./candran/can-parser/parser.lua:808 +lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:809 +local ast, label, errpos = lpeg["match"](macroidentifier, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:810 +if not ast then -- ./candran/can-parser/parser.lua:811 +local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:812 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:813 +end -- ./candran/can-parser/parser.lua:813 +return ast -- ./candran/can-parser/parser.lua:815 +end -- ./candran/can-parser/parser.lua:815 +return parser -- ./candran/can-parser/parser.lua:818 +end -- ./candran/can-parser/parser.lua:818 +local parser = _() or parser -- ./candran/can-parser/parser.lua:822 +package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:823 +local unpack = unpack or table["unpack"] -- candran.can:21 +candran["default"] = { -- candran.can:24 +["target"] = "lua55", -- candran.can:25 +["indentation"] = "", -- candran.can:26 ["newline"] = "\ -", -- candran.can:26 -["variablePrefix"] = "__CAN_", -- candran.can:27 -["mapLines"] = true, -- candran.can:28 -["chunkname"] = "nil", -- candran.can:29 -["rewriteErrors"] = true, -- candran.can:30 -["builtInMacros"] = true, -- candran.can:31 -["preprocessorEnv"] = {}, -- candran.can:32 -["import"] = {} -- candran.can:33 -} -- candran.can:33 -if _VERSION == "Lua 5.1" then -- candran.can:37 -if package["loaded"]["jit"] then -- candran.can:38 -candran["default"]["target"] = "luajit" -- candran.can:39 -else -- candran.can:39 -candran["default"]["target"] = "lua51" -- candran.can:41 -end -- candran.can:41 -elseif _VERSION == "Lua 5.2" then -- candran.can:43 -candran["default"]["target"] = "lua52" -- candran.can:44 -elseif _VERSION == "Lua 5.3" then -- candran.can:45 -candran["default"]["target"] = "lua53" -- candran.can:46 -end -- candran.can:46 -candran["preprocess"] = function(input, options, _env) -- candran.can:56 -if options == nil then options = {} end -- candran.can:56 -options = util["merge"](candran["default"], options) -- candran.can:57 -local macros = { -- candran.can:58 -["functions"] = {}, -- candran.can:59 -["variables"] = {} -- candran.can:60 -} -- candran.can:60 -for _, mod in ipairs(options["import"]) do -- candran.can:64 +", -- candran.can:27 +["variablePrefix"] = "__CAN_", -- candran.can:28 +["mapLines"] = true, -- candran.can:29 +["chunkname"] = "nil", -- candran.can:30 +["rewriteErrors"] = true, -- candran.can:31 +["builtInMacros"] = true, -- candran.can:32 +["preprocessorEnv"] = {}, -- candran.can:33 +["import"] = {} -- candran.can:34 +} -- candran.can:34 +if _VERSION == "Lua 5.1" then -- candran.can:38 +if package["loaded"]["jit"] then -- candran.can:39 +candran["default"]["target"] = "luajit" -- candran.can:40 +else -- candran.can:40 +candran["default"]["target"] = "lua51" -- candran.can:42 +end -- candran.can:42 +elseif _VERSION == "Lua 5.2" then -- candran.can:44 +candran["default"]["target"] = "lua52" -- candran.can:45 +elseif _VERSION == "Lua 5.3" then -- candran.can:46 +candran["default"]["target"] = "lua53" -- candran.can:47 +elseif _VERSION == "Lua 5.4" then -- candran.can:48 +candran["default"]["target"] = "lua54" -- candran.can:49 +end -- candran.can:49 +candran["preprocess"] = function(input, options, _env) -- candran.can:59 +if options == nil then options = {} end -- candran.can:59 +options = util["merge"](candran["default"], options) -- candran.can:60 +local macros = { -- candran.can:61 +["functions"] = {}, -- candran.can:62 +["variables"] = {} -- candran.can:63 +} -- candran.can:63 +for _, mod in ipairs(options["import"]) do -- candran.can:67 input = (("#import(%q, {loadLocal=false})\ -"):format(mod)) .. input -- candran.can:65 -end -- candran.can:65 -local preprocessor = "" -- candran.can:69 -local i = 0 -- candran.can:70 -local inLongString = false -- candran.can:71 -local inComment = false -- candran.can:72 +"):format(mod)) .. input -- candran.can:68 +end -- candran.can:68 +local preprocessor = "" -- candran.can:72 +local i = 0 -- candran.can:73 +local inLongString = false -- candran.can:74 +local inComment = false -- candran.can:75 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:73 -i = i + (1) -- candran.can:74 -if inComment then -- candran.can:76 -inComment = not line:match("%]%]") -- candran.can:77 -elseif inLongString then -- candran.can:78 -inLongString = not line:match("%]%]") -- candran.can:79 -else -- candran.can:79 -if line:match("[^%-]%[%[") then -- candran.can:81 -inLongString = true -- candran.can:82 -elseif line:match("%-%-%[%[") then -- candran.can:83 -inComment = true -- candran.can:84 -end -- candran.can:84 -end -- candran.can:84 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:87 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:88 -else -- candran.can:88 -local l = line:sub(1, - 2) -- candran.can:90 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:91 +)") do -- candran.can:76 +i = i + (1) -- candran.can:77 +if inComment then -- candran.can:79 +inComment = not line:match("%]%]") -- candran.can:80 +elseif inLongString then -- candran.can:81 +inLongString = not line:match("%]%]") -- candran.can:82 +else -- candran.can:82 +if line:match("[^%-]%[%[") then -- candran.can:84 +inLongString = true -- candran.can:85 +elseif line:match("%-%-%[%[") then -- candran.can:86 +inComment = true -- candran.can:87 +end -- candran.can:87 +end -- candran.can:87 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:90 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:91 +else -- candran.can:91 +local l = line:sub(1, - 2) -- candran.can:93 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:94 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:92 -else -- candran.can:92 +") -- candran.can:95 +else -- candran.can:95 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:94 -end -- candran.can:94 -end -- candran.can:94 -end -- candran.can:94 -preprocessor = preprocessor .. ("return output") -- candran.can:98 -local exportenv = {} -- candran.can:101 -local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:102 -env["candran"] = candran -- candran.can:104 -env["output"] = "" -- candran.can:106 -env["import"] = function(modpath, margs) -- candran.can:113 -if margs == nil then margs = {} end -- candran.can:113 -local filepath = assert(util["search"](modpath, { -- candran.can:114 -"can", -- candran.can:114 -"lua" -- candran.can:114 -}), "No module named \"" .. modpath .. "\"") -- candran.can:114 -local f = io["open"](filepath) -- candran.can:117 -if not f then -- candran.can:118 -error("can't open the module file to import") -- candran.can:118 -end -- candran.can:118 -margs = util["merge"](options, { -- candran.can:120 -["chunkname"] = filepath, -- candran.can:120 -["loadLocal"] = true, -- candran.can:120 -["loadPackage"] = true -- candran.can:120 -}, margs) -- candran.can:120 -margs["import"] = {} -- candran.can:121 -local modcontent, modmacros, modenv = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:122 -macros = util["recmerge"](macros, modmacros) -- candran.can:123 -for k, v in pairs(modenv) do -- candran.can:124 -env[k] = v -- candran.can:124 -end -- candran.can:124 -f:close() -- candran.can:125 -local modname = modpath:match("[^%.]+$") -- candran.can:128 +") -- candran.can:97 +end -- candran.can:97 +end -- candran.can:97 +end -- candran.can:97 +preprocessor = preprocessor .. ("return output") -- candran.can:101 +local exportenv = {} -- candran.can:104 +local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:105 +env["candran"] = candran -- candran.can:107 +env["output"] = "" -- candran.can:109 +env["import"] = function(modpath, margs) -- candran.can:116 +if margs == nil then margs = {} end -- candran.can:116 +local filepath = assert(util["search"](modpath, { -- candran.can:117 +"can", -- candran.can:117 +"lua" -- candran.can:117 +}), "No module named \"" .. modpath .. "\"") -- candran.can:117 +local f = io["open"](filepath) -- candran.can:120 +if not f then -- candran.can:121 +error("can't open the module file to import") -- candran.can:121 +end -- candran.can:121 +margs = util["merge"](options, { -- candran.can:123 +["chunkname"] = filepath, -- candran.can:123 +["loadLocal"] = true, -- candran.can:123 +["loadPackage"] = true -- candran.can:123 +}, margs) -- candran.can:123 +margs["import"] = {} -- candran.can:124 +local modcontent, modmacros, modenv = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:125 +macros = util["recmerge"](macros, modmacros) -- candran.can:126 +for k, v in pairs(modenv) do -- candran.can:127 +env[k] = v -- candran.can:127 +end -- candran.can:127 +f:close() -- candran.can:128 +local modname = modpath:match("[^%.]+$") -- candran.can:131 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:137 -end -- candran.can:137 -env["include"] = function(file) -- candran.can:142 -local f = io["open"](file) -- candran.can:143 -if not f then -- candran.can:144 -error("can't open the file " .. file .. " to include") -- candran.can:144 -end -- candran.can:144 -env["write"](f:read("*a")) -- candran.can:145 -f:close() -- candran.can:146 -end -- candran.can:146 -env["write"] = function(...) -- candran.can:150 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:140 +end -- candran.can:140 +env["include"] = function(file) -- candran.can:145 +local f = io["open"](file) -- candran.can:146 +if not f then -- candran.can:147 +error("can't open the file " .. file .. " to include") -- candran.can:147 +end -- candran.can:147 +env["write"](f:read("*a")) -- candran.can:148 +f:close() -- candran.can:149 +end -- candran.can:149 +env["write"] = function(...) -- candran.can:153 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:151 -end -- candran.can:151 -env["placeholder"] = function(name) -- candran.can:155 -if env[name] then -- candran.can:156 -env["write"](env[name]) -- candran.can:157 -end -- candran.can:157 -end -- candran.can:157 -env["define"] = function(identifier, replacement) -- candran.can:160 -local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:162 -if not iast then -- candran.can:163 -return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:164 -end -- candran.can:164 -if type(replacement) == "string" then -- candran.can:167 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:168 -if not rast then -- candran.can:169 -return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:170 -end -- candran.can:170 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:173 -rast = rast[1][1] -- candran.can:174 -end -- candran.can:174 -replacement = rast -- candran.can:176 -elseif type(replacement) ~= "function" then -- candran.can:177 -error("bad argument #2 to 'define' (string or function expected)") -- candran.can:178 -end -- candran.can:178 -if iast["tag"] == "MacroFunction" then -- candran.can:181 -macros["functions"][iast[1][1]] = { -- candran.can:182 -["args"] = iast[2], -- candran.can:182 -["replacement"] = replacement -- candran.can:182 -} -- candran.can:182 -elseif iast["tag"] == "Id" then -- candran.can:183 -macros["variables"][iast[1]] = replacement -- candran.can:184 -else -- candran.can:184 -error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:186 -end -- candran.can:186 -end -- candran.can:186 -env["set"] = function(identifier, value) -- candran.can:189 -exportenv[identifier] = value -- candran.can:190 -env[identifier] = value -- candran.can:191 -end -- candran.can:191 -if options["builtInMacros"] then -- candran.can:195 -env["define"]("__STR__(x)", function(x) -- candran.can:196 -return ("%q"):format(x) -- candran.can:196 -end) -- candran.can:196 -local s = require("candran.serpent") -- candran.can:197 -env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:198 -return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:199 +") -- candran.can:154 +end -- candran.can:154 +env["placeholder"] = function(name) -- candran.can:158 +if env[name] then -- candran.can:159 +env["write"](env[name]) -- candran.can:160 +end -- candran.can:160 +end -- candran.can:160 +env["define"] = function(identifier, replacement) -- candran.can:163 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:165 +if not iast then -- candran.can:166 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:167 +end -- candran.can:167 +if type(replacement) == "string" then -- candran.can:170 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:171 +if not rast then -- candran.can:172 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:173 +end -- candran.can:173 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:176 +rast = rast[1][1] -- candran.can:177 +end -- candran.can:177 +replacement = rast -- candran.can:179 +elseif type(replacement) ~= "function" then -- candran.can:180 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:181 +end -- candran.can:181 +if iast["tag"] == "MacroFunction" then -- candran.can:184 +macros["functions"][iast[1][1]] = { -- candran.can:185 +["args"] = iast[2], -- candran.can:185 +["replacement"] = replacement -- candran.can:185 +} -- candran.can:185 +elseif iast["tag"] == "Id" then -- candran.can:186 +macros["variables"][iast[1]] = replacement -- candran.can:187 +else -- candran.can:187 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:189 +end -- candran.can:189 +end -- candran.can:189 +env["set"] = function(identifier, value) -- candran.can:192 +exportenv[identifier] = value -- candran.can:193 +env[identifier] = value -- candran.can:194 +end -- candran.can:194 +if options["builtInMacros"] then -- candran.can:198 +env["define"]("__STR__(x)", function(x) -- candran.can:199 +return ("%q"):format(x) -- candran.can:199 end) -- candran.can:199 -end -- candran.can:199 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:204 -if not preprocess then -- candran.can:205 -return nil, "in preprocessor: " .. err -- candran.can:206 -end -- candran.can:206 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:209 -if not preprocess then -- candran.can:210 -return nil, "in preprocessor: " .. err -- candran.can:211 -end -- candran.can:211 -local success, output = pcall(preprocess) -- candran.can:215 -if not success then -- candran.can:216 -return nil, "in preprocessor: " .. output -- candran.can:217 -end -- candran.can:217 -return output, macros, exportenv -- candran.can:220 +local s = require("candran.serpent") -- candran.can:200 +env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:201 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:202 +end) -- candran.can:202 +end -- candran.can:202 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:207 +if not preprocess then -- candran.can:208 +return nil, "in preprocessor: " .. err -- candran.can:209 +end -- candran.can:209 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:212 +if not preprocess then -- candran.can:213 +return nil, "in preprocessor: " .. err -- candran.can:214 +end -- candran.can:214 +local success, output = pcall(preprocess) -- candran.can:218 +if not success then -- candran.can:219 +return nil, "in preprocessor: " .. output -- candran.can:220 end -- candran.can:220 -candran["compile"] = function(input, options, macros) -- candran.can:230 -if options == nil then options = {} end -- candran.can:230 -options = util["merge"](candran["default"], options) -- candran.can:231 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:233 -if not ast then -- candran.can:235 -return nil, errmsg -- candran.can:236 -end -- candran.can:236 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:239 +return output, macros, exportenv -- candran.can:223 +end -- candran.can:223 +candran["compile"] = function(input, options, macros) -- candran.can:233 +if options == nil then options = {} end -- candran.can:233 +options = util["merge"](candran["default"], options) -- candran.can:234 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:236 +if not ast then -- candran.can:238 +return nil, errmsg -- candran.can:239 end -- candran.can:239 -candran["make"] = function(code, options) -- candran.can:248 -local r, err = candran["preprocess"](code, options) -- candran.can:249 -if r then -- candran.can:250 -r, err = candran["compile"](r, options, err) -- candran.can:251 -if r then -- candran.can:252 -return r -- candran.can:253 -end -- candran.can:253 -end -- candran.can:253 -return r, err -- candran.can:256 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:242 +end -- candran.can:242 +candran["make"] = function(code, options) -- candran.can:251 +local r, err = candran["preprocess"](code, options) -- candran.can:252 +if r then -- candran.can:253 +r, err = candran["compile"](r, options, err) -- candran.can:254 +if r then -- candran.can:255 +return r -- candran.can:256 end -- candran.can:256 -local errorRewritingActive = false -- candran.can:259 -local codeCache = {} -- candran.can:260 -candran["loadfile"] = function(filepath, env, options) -- candran.can:263 -local f, err = io["open"](filepath) -- candran.can:264 -if not f then -- candran.can:265 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:266 -end -- candran.can:266 -local content = f:read("*a") -- candran.can:268 -f:close() -- candran.can:269 -return candran["load"](content, filepath, env, options) -- candran.can:271 -end -- candran.can:271 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:276 -if options == nil then options = {} end -- candran.can:276 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:277 -local code, err = candran["make"](chunk, options) -- candran.can:279 -if not code then -- candran.can:280 -return code, err -- candran.can:281 -end -- candran.can:281 -codeCache[options["chunkname"]] = code -- candran.can:284 -local f -- candran.can:285 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:286 -if f == nil then -- candran.can:291 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:292 -end -- candran.can:292 -if options["rewriteErrors"] == false then -- candran.can:295 -return f -- candran.can:296 -else -- candran.can:296 -return function(...) -- candran.can:298 -if not errorRewritingActive then -- candran.can:299 -errorRewritingActive = true -- candran.can:300 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:301 -errorRewritingActive = false -- candran.can:302 -if t[1] == false then -- candran.can:303 -error(t[2], 0) -- candran.can:304 -end -- candran.can:304 -return unpack(t, 2) -- candran.can:306 -else -- candran.can:306 -return f(...) -- candran.can:308 -end -- candran.can:308 -end -- candran.can:308 -end -- candran.can:308 -end -- candran.can:308 -candran["dofile"] = function(filename, options) -- candran.can:316 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:317 -if f == nil then -- candran.can:319 -error(err) -- candran.can:320 -else -- candran.can:320 -return f() -- candran.can:322 -end -- candran.can:322 -end -- candran.can:322 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:328 -message = tostring(message) -- candran.can:329 +end -- candran.can:256 +return r, err -- candran.can:259 +end -- candran.can:259 +local errorRewritingActive = false -- candran.can:262 +local codeCache = {} -- candran.can:263 +candran["loadfile"] = function(filepath, env, options) -- candran.can:266 +local f, err = io["open"](filepath) -- candran.can:267 +if not f then -- candran.can:268 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:269 +end -- candran.can:269 +local content = f:read("*a") -- candran.can:271 +f:close() -- candran.can:272 +return candran["load"](content, filepath, env, options) -- candran.can:274 +end -- candran.can:274 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:279 +if options == nil then options = {} end -- candran.can:279 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:280 +local code, err = candran["make"](chunk, options) -- candran.can:282 +if not code then -- candran.can:283 +return code, err -- candran.can:284 +end -- candran.can:284 +codeCache[options["chunkname"]] = code -- candran.can:287 +local f -- candran.can:288 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:289 +if f == nil then -- candran.can:294 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:295 +end -- candran.can:295 +if options["rewriteErrors"] == false then -- candran.can:298 +return f -- candran.can:299 +else -- candran.can:299 +return function(...) -- candran.can:301 +if not errorRewritingActive then -- candran.can:302 +errorRewritingActive = true -- candran.can:303 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:304 +errorRewritingActive = false -- candran.can:305 +if t[1] == false then -- candran.can:306 +error(t[2], 0) -- candran.can:307 +end -- candran.can:307 +return unpack(t, 2) -- candran.can:309 +else -- candran.can:309 +return f(...) -- candran.can:311 +end -- candran.can:311 +end -- candran.can:311 +end -- candran.can:311 +end -- candran.can:311 +candran["dofile"] = function(filename, options) -- candran.can:319 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:320 +if f == nil then -- candran.can:322 +error(err) -- candran.can:323 +else -- candran.can:323 +return f() -- candran.can:325 +end -- candran.can:325 +end -- candran.can:325 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:331 +message = tostring(message) -- candran.can:332 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:330 -message = debug["traceback"](message, 2) -- candran.can:331 -end -- candran.can:331 +") then -- candran.can:333 +message = debug["traceback"](message, 2) -- candran.can:334 +end -- candran.can:334 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:333 -line = tonumber(line) -- candran.can:334 -local originalFile -- candran.can:336 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:337 -if strName then -- candran.can:338 -if codeCache[strName] then -- candran.can:339 -originalFile = codeCache[strName] -- candran.can:340 -source = strName -- candran.can:341 -end -- candran.can:341 -else -- candran.can:341 -do -- candran.can:344 -local fi -- candran.can:344 -fi = io["open"](source, "r") -- candran.can:344 -if fi then -- candran.can:344 -originalFile = fi:read("*a") -- candran.can:345 -fi:close() -- candran.can:346 -end -- candran.can:346 -end -- candran.can:346 -end -- candran.can:346 -if originalFile then -- candran.can:350 -local i = 0 -- candran.can:351 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:336 +line = tonumber(line) -- candran.can:337 +local originalFile -- candran.can:339 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:340 +if strName then -- candran.can:341 +if codeCache[strName] then -- candran.can:342 +originalFile = codeCache[strName] -- candran.can:343 +source = strName -- candran.can:344 +end -- candran.can:344 +else -- candran.can:344 +do -- candran.can:347 +local fi -- candran.can:347 +fi = io["open"](source, "r") -- candran.can:347 +if fi then -- candran.can:347 +originalFile = fi:read("*a") -- candran.can:348 +fi:close() -- candran.can:349 +end -- candran.can:349 +end -- candran.can:349 +end -- candran.can:349 +if originalFile then -- candran.can:353 +local i = 0 -- candran.can:354 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:352 -i = i + 1 -- candran.can:353 -if i == line then -- candran.can:354 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:355 -if lineMap then -- candran.can:356 -if extSource ~= source then -- candran.can:357 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:358 -else -- candran.can:358 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:360 -end -- candran.can:360 -end -- candran.can:360 -break -- candran.can:363 +") do -- candran.can:355 +i = i + 1 -- candran.can:356 +if i == line then -- candran.can:357 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:358 +if lineMap then -- candran.can:359 +if extSource ~= source then -- candran.can:360 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:361 +else -- candran.can:361 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:363 end -- candran.can:363 end -- candran.can:363 -end -- candran.can:363 -end) -- candran.can:363 -end -- candran.can:363 -candran["searcher"] = function(modpath) -- candran.can:371 -local filepath = util["search"](modpath, { "can" }) -- candran.can:372 -if not filepath then -- candran.can:373 -if _VERSION == "Lua 5.4" then -- candran.can:374 -return "no candran file in package.path" -- candran.can:375 -else -- candran.can:375 +break -- candran.can:366 +end -- candran.can:366 +end -- candran.can:366 +end -- candran.can:366 +end) -- candran.can:366 +end -- candran.can:366 +candran["searcher"] = function(modpath) -- candran.can:374 +local filepath = util["search"](modpath, { "can" }) -- candran.can:375 +if not filepath then -- candran.can:376 +if _VERSION == "Lua 5.4" then -- candran.can:377 +return "no candran file in package.path" -- candran.can:378 +else -- candran.can:378 return "\ -\9no candran file in package.path" -- candran.can:377 -end -- candran.can:377 -end -- candran.can:377 -return function(modpath) -- candran.can:380 -local r, s = candran["loadfile"](filepath) -- candran.can:381 -if r then -- candran.can:382 -return r(modpath, filepath) -- candran.can:383 -else -- candran.can:383 +\9no candran file in package.path" -- candran.can:380 +end -- candran.can:380 +end -- candran.can:380 +return function(modpath) -- candran.can:383 +local r, s = candran["loadfile"](filepath) -- candran.can:384 +if r then -- candran.can:385 +return r(modpath, filepath) -- candran.can:386 +else -- candran.can:386 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:385 -end -- candran.can:385 -end, filepath -- candran.can:387 -end -- candran.can:387 -candran["setup"] = function() -- candran.can:391 -local searchers = (function() -- candran.can:392 -if _VERSION == "Lua 5.1" then -- candran.can:392 -return package["loaders"] -- candran.can:393 -else -- candran.can:393 -return package["searchers"] -- candran.can:395 -end -- candran.can:395 -end)() -- candran.can:395 -for _, s in ipairs(searchers) do -- candran.can:398 -if s == candran["searcher"] then -- candran.can:399 -return candran -- candran.can:400 -end -- candran.can:400 -end -- candran.can:400 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:404 -return candran -- candran.can:405 -end -- candran.can:405 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:388 +end -- candran.can:388 +end, filepath -- candran.can:390 +end -- candran.can:390 +candran["setup"] = function() -- candran.can:394 +local searchers = (function() -- candran.can:395 +if _VERSION == "Lua 5.1" then -- candran.can:395 +return package["loaders"] -- candran.can:396 +else -- candran.can:396 +return package["searchers"] -- candran.can:398 +end -- candran.can:398 +end)() -- candran.can:398 +for _, s in ipairs(searchers) do -- candran.can:401 +if s == candran["searcher"] then -- candran.can:402 +return candran -- candran.can:403 +end -- candran.can:403 +end -- candran.can:403 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:407 return candran -- candran.can:408 +end -- candran.can:408 +return candran -- candran.can:411 From 69cb2f9232916845819c3c63c8b1d27c467f9c0b Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:24:14 +0100 Subject: [PATCH 09/11] =?UTF-8?q?docs:=20bump=20version=20to=201.1.=C2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- candran.can | 2 +- candran.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ac241ea..b2fec22 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ end ```` -**Current status**: Candran is heavily used in several of my personal projects and works as expected. +**Current status**: Candran is stable ; I use it heavily used in several of my personal projects and maintain it. If there's no activity on the repo, it means there's no bug or new Lua version that requires an update. Candran is released under the MIT License (see ```LICENSE``` for details). diff --git a/candran.can b/candran.can index 29e73e2..f9f9397 100644 --- a/candran.can +++ b/candran.can @@ -1,5 +1,5 @@ local candran = { - VERSION = "1.0.0" + VERSION = "1.1.0" } package.loaded["candran"] = candran diff --git a/candran.lua b/candran.lua index 18004eb..c4691d3 100644 --- a/candran.lua +++ b/candran.lua @@ -1,4 +1,4 @@ -local candran = { ["VERSION"] = "1.0.0" } -- candran.can:2 +local candran = { ["VERSION"] = "1.1.0" } -- candran.can:2 package["loaded"]["candran"] = candran -- candran.can:4 local function _() -- candran.can:7 local candran = require("candran") -- ./candran/util.can:1 From 4e05ac93202703016941b0ca95f560014c19c2ae Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:29:01 +0100 Subject: [PATCH 10/11] feat: update rockspec to 1.1.0 --- .../{candran-1.0.0-1.rockspec => candran-1.1.0-1.rockspec} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename rockspec/{candran-1.0.0-1.rockspec => candran-1.1.0-1.rockspec} (78%) diff --git a/rockspec/candran-1.0.0-1.rockspec b/rockspec/candran-1.1.0-1.rockspec similarity index 78% rename from rockspec/candran-1.0.0-1.rockspec rename to rockspec/candran-1.1.0-1.rockspec index d291e73..6053055 100644 --- a/rockspec/candran-1.0.0-1.rockspec +++ b/rockspec/candran-1.1.0-1.rockspec @@ -2,12 +2,12 @@ rockspec_format = "3.0" package = "candran" -version = "1.0.0-1" +version = "1.1.0-1" description = { summary = "A simple Lua dialect and preprocessor.", detailed = [[ - Candran is a dialect of the Lua 5.4 programming language which compiles to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. + Candran is a dialect of the Lua 5.4 programming language which compiles to Lua 5.5, Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. ]], license = "MIT", @@ -19,7 +19,7 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v1.0.0" + tag = "v1.1.0" } dependencies = { From 3dc6ad3cf5c20001e1ef61d923cb95617356a557 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 26 Dec 2025 15:48:21 +0100 Subject: [PATCH 11/11] fix: fix Lua 5.5 tests --- test/test.lua | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/test.lua b/test/test.lua index 30fc457..5ce0830 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1157,20 +1157,21 @@ foo = 12 ]]) if _VERSION >= "Lua 5.5" then test("global variable declaration", [[ - do - global foo - global bar - end - foo = 42 - assert(not pcall(function() foo = 42 end)) + global foo = 42 ]]) + test("global variable declaration with error", [[ + global foo = 42 + bar = 12 + ]], { "loadError", "variable 'bar' not declared" }) + test("global variable declaration with attribute", [[ + global bar + bar = 42 + ]], { "loadError", "attempt to assign to const variable 'bar'" }) test("collective global variable declaration with attribute", [[ foo = 42 - do - global * - end - assert(not pcall(function() foo = 12 end)) - ]]) + global * + foo = 12 + ]], { "loadError", "attempt to assign to const variable 'foo'" }) end -- bitwise operators