diff --git a/README.md b/README.md index cf6868e..0fd8a75 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ end let a = { hey = true, + child = nil, + method = :(foo, thing) -- short function declaration, with self @hey = thing(foo) -- @ as an alias for self end, @@ -33,6 +35,13 @@ a:method(42, (foo) return "something " .. foo end) +local fn = a:method -- bundles an object and method in a function +fn(42, (foo) + return "something" .. foo +end) + +a.child?:method?() -- safe navigation operator + local odd = [ -- table comprehension for i=1, 10 do if i%2 == 0 then @@ -48,6 +57,12 @@ 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 +if f, err = io.open("data") then -- if condition with assignements + thing.process(f) +else + error("can't open data: "..err) +end + ```` **Current status**: Candran is heavily used in several of my personal projects and works as expected. @@ -97,7 +112,7 @@ All theses operators can also be put right of the assigment operator, in which c Right and left operator can be used at the same time. -**Please note** that the Lua code `a=-1` will be compiled into `a = 1 - a` and not `a = -1`! Write spaced code: `a = -1` works as expected. +**Please note** that the code `a=-1` will be compiled into `a = -1` and not `a = a - 1`, like in pure Lua. If you want the latter, spacing is required between the `=-` and the expression: `a=- 1`. Yes, this is also valid Lua code, but as far as I'm aware, nobody write code like this; people who really like spacing would write `a= - 1` or `a = - 1`, and Candran will read both of those as it is expected in pure Lua. This is the only incompatibility between Candran and pure Lua. ##### Default function parameters ```lua @@ -230,6 +245,68 @@ 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. +##### Safe navigation operators +```lua +a = nil +print(a?.b) -- nil + +a = {b=true} +print(a?.b) -- true + +-- So instead of typing +if object and object.child and object.child.isGreen then + -- stuff +end +-- you can type +if object?.child?.isGreen then + -- stuff +end + +-- The ?. operator does not break the whole chain; make sure to use the operator on each index. +print(a?.undefined.field) -- a?.undefined returns nil, so this throws a "attempt to index a nil value" + +-- Other safe navigator operators behave similarly: +print(a:method) -- nil if a is nil, other normal behaviour +print(a["key"]) -- nil if a is nil, other normal behaviour +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 +```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 + f:close() +elseif f2, err2 = io.open("anotherfile") then -- same behaviour on elseif + print("could not open somefile:", err) -- f and err stay in scope for the rest of the if-elseif-else block + -- do something with f2 + f2:close() +else + print("could not open somefile:", err) + print("could not open anotherfile:", err2) +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. + print(index, value) +end + +-- When used in a while, the expression is evaluated at each iteration. +while line = io.read() do + print(line) +end + +-- The assignement have the same priority as regular assignements, 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. + +For while statements, the assigned expression will be reevaluated at each iteration. + ##### Suffixable string and table litterals ```lua "some text":upper() -- "SOME TEXT". Same as ("some text"):upper() in Lua. @@ -246,6 +323,27 @@ String litterals, table litterals, and comprehensions can be suffixed with `:` m **Please note**, that "normal" functions calls have priority over this syntax, in order to maintain Lua compatibility. +##### Method stubs +```lua +object = { + value = 25, + method = function(self, str) + print(str, self.value) + end +} + +stub = object:method + +object.method = error -- stub stores the method as it was when stub was defined +object = nil -- also stores the object + +print(stub("hello")) -- hello 25 +``` + +Create a closure function which bundles the variable and its method; when called it will call the method on the variable, without requiring to pass the variable as a first argument. + +The closure stores the value of the variable and method when created. + ##### Statement expressions ```lua a = if false then diff --git a/candran.can b/candran.can index e3df888..b1e7af0 100644 --- a/candran.can +++ b/candran.can @@ -86,7 +86,7 @@ function candran.preprocess(input, options={}) -- @tparam modpath string module path -- @tparam margs table preprocessor options to use when preprocessessing the module env.import = function(modpath, margs={}) - local filepath = assert(util.search(modpath), "No module named \""..modpath.."\"") + local filepath = assert(util.search(modpath, {"can", "lua"}), "No module named \""..modpath.."\"") -- open module file local f = io.open(filepath) diff --git a/candran.lua b/candran.lua index 4867f48..94bb82f 100644 --- a/candran.lua +++ b/candran.lua @@ -1,10 +1,7 @@ local function _() -- candran.can:2 local util = {} -- ./lib/util.can:1 util["search"] = function(modpath, exts) -- ./lib/util.can:3 -if exts == nil then exts = { -- ./lib/util.can:3 -"can", -- ./lib/util.can:3 -"lua" -- ./lib/util.can:3 -} end -- ./lib/util.can:3 +if exts == nil then exts = {} end -- ./lib/util.can:3 for _, ext in ipairs(exts) do -- ./lib/util.can:4 for path in package["path"]:gmatch("[^;]+") do -- ./lib/util.can:5 local fpath = path:gsub("%.lua", "." .. ext):gsub("%?", (modpath:gsub("%.", "/"))) -- ./lib/util.can:6 @@ -132,1836 +129,2210 @@ end -- ./lib/cmdline.lua:125 local cmdline = _() or cmdline -- ./lib/cmdline.lua:130 package["loaded"]["lib.cmdline"] = cmdline or true -- ./lib/cmdline.lua:131 local function _() -- ./lib/cmdline.lua:135 -return function(code, ast, options) -- ./compiler/lua53.can:1 -local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:3 -local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:4 -local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:5 -local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:6 -local indentLevel = 0 -- ./compiler/lua53.can:9 -local function newline() -- ./compiler/lua53.can:11 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:12 -if options["mapLines"] then -- ./compiler/lua53.can:13 -local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:14 +local targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +return function(code, ast, options) -- ./compiler/lua53.can:3 +local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:7 +local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:8 +local indentLevel = 0 -- ./compiler/lua53.can:11 +local function newline() -- ./compiler/lua53.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:14 +if options["mapLines"] then -- ./compiler/lua53.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:16 local source, line = sub:sub(1, sub:find("\ ")):match("%-%- (.-)%:(%d+)\ -") -- ./compiler/lua53.can:15 -if source and line then -- ./compiler/lua53.can:17 -lastSource = source -- ./compiler/lua53.can:18 -lastLine = tonumber(line) -- ./compiler/lua53.can:19 -else -- ./compiler/lua53.can:19 +") -- ./compiler/lua53.can:17 +if source and line then -- ./compiler/lua53.can:19 +lastSource = source -- ./compiler/lua53.can:20 +lastLine = tonumber(line) -- ./compiler/lua53.can:21 +else -- ./compiler/lua53.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua53.can:21 -lastLine = lastLine + (1) -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -prevLinePos = lastInputPos -- ./compiler/lua53.can:26 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:28 -end -- ./compiler/lua53.can:28 -return r -- ./compiler/lua53.can:30 +") do -- ./compiler/lua53.can:23 +lastLine = lastLine + (1) -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +prevLinePos = lastInputPos -- ./compiler/lua53.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:30 end -- ./compiler/lua53.can:30 -local function indent() -- ./compiler/lua53.can:33 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:34 -return newline() -- ./compiler/lua53.can:35 -end -- ./compiler/lua53.can:35 -local function unindent() -- ./compiler/lua53.can:38 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:39 -return newline() -- ./compiler/lua53.can:40 -end -- ./compiler/lua53.can:40 -local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:44 -local requireStr = "" -- ./compiler/lua53.can:45 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:47 -if not required[mod] then -- ./compiler/lua53.can:48 -requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:49 -required[mod] = true -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -local function var(name) -- ./compiler/lua53.can:56 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:57 -end -- ./compiler/lua53.can:57 -local loop = { -- loops tags -- ./compiler/lua53.can:61 -"While", -- loops tags -- ./compiler/lua53.can:61 -"Repeat", -- loops tags -- ./compiler/lua53.can:61 -"Fornum", -- loops tags -- ./compiler/lua53.can:61 -"Forin" -- loops tags -- ./compiler/lua53.can:61 -} -- loops tags -- ./compiler/lua53.can:61 -local func = { -- function scope tags -- ./compiler/lua53.can:62 -"Function", -- function scope tags -- ./compiler/lua53.can:62 -"TableCompr", -- function scope tags -- ./compiler/lua53.can:62 -"DoExpr", -- function scope tags -- ./compiler/lua53.can:62 -"WhileExpr", -- function scope tags -- ./compiler/lua53.can:62 -"RepeatExpr", -- function scope tags -- ./compiler/lua53.can:62 -"IfExpr", -- function scope tags -- ./compiler/lua53.can:62 -"FornumExpr", -- function scope tags -- ./compiler/lua53.can:62 -"ForinExpr" -- function scope tags -- ./compiler/lua53.can:62 -} -- function scope tags -- ./compiler/lua53.can:62 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:65 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:65 -local tagsCheck = {} -- ./compiler/lua53.can:66 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:67 -tagsCheck[tag] = true -- ./compiler/lua53.can:68 -end -- ./compiler/lua53.can:68 -local nofollowCheck = {} -- ./compiler/lua53.can:70 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:71 -nofollowCheck[tag] = true -- ./compiler/lua53.can:72 -end -- ./compiler/lua53.can:72 -for _, node in ipairs(list) do -- ./compiler/lua53.can:74 -if type(node) == "table" then -- ./compiler/lua53.can:75 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:76 -return node -- ./compiler/lua53.can:77 -end -- ./compiler/lua53.can:77 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:79 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:80 -if r then -- ./compiler/lua53.can:81 -return r -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -return nil -- ./compiler/lua53.can:85 -end -- ./compiler/lua53.can:85 -local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:91 -local function push(name, state) -- ./compiler/lua53.can:94 -table["insert"](states[name], state) -- ./compiler/lua53.can:95 -return "" -- ./compiler/lua53.can:96 +return r -- ./compiler/lua53.can:32 +end -- ./compiler/lua53.can:32 +local function indent() -- ./compiler/lua53.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:36 +return newline() -- ./compiler/lua53.can:37 +end -- ./compiler/lua53.can:37 +local function unindent() -- ./compiler/lua53.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 +return newline() -- ./compiler/lua53.can:42 +end -- ./compiler/lua53.can:42 +local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:46 +local requireStr = "" -- ./compiler/lua53.can:47 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:49 +if not required[mod] then -- ./compiler/lua53.can:50 +requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:51 +required[mod] = true -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +local function var(name) -- ./compiler/lua53.can:58 +return options["variablePrefix"] .. name -- ./compiler/lua53.can:59 +end -- ./compiler/lua53.can:59 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:68 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:68 +local tagsCheck = {} -- ./compiler/lua53.can:69 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:70 +tagsCheck[tag] = true -- ./compiler/lua53.can:71 +end -- ./compiler/lua53.can:71 +local nofollowCheck = {} -- ./compiler/lua53.can:73 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:74 +nofollowCheck[tag] = true -- ./compiler/lua53.can:75 +end -- ./compiler/lua53.can:75 +for _, node in ipairs(list) do -- ./compiler/lua53.can:77 +if type(node) == "table" then -- ./compiler/lua53.can:78 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:79 +return node -- ./compiler/lua53.can:80 +end -- ./compiler/lua53.can:80 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:82 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:83 +if r then -- ./compiler/lua53.can:84 +return r -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +return nil -- ./compiler/lua53.can:88 +end -- ./compiler/lua53.can:88 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:93 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:93 +local tagsCheck = {} -- ./compiler/lua53.can:94 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:95 +tagsCheck[tag] = true -- ./compiler/lua53.can:96 end -- ./compiler/lua53.can:96 -local function pop(name) -- ./compiler/lua53.can:99 -table["remove"](states[name]) -- ./compiler/lua53.can:100 -return "" -- ./compiler/lua53.can:101 -end -- ./compiler/lua53.can:101 -local function peek(name) -- ./compiler/lua53.can:104 -return states[name][# states[name]] -- ./compiler/lua53.can:105 -end -- ./compiler/lua53.can:105 -local tags -- ./compiler/lua53.can:109 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:111 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:112 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:113 -end -- ./compiler/lua53.can:113 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:115 +local nofollowCheck = {} -- ./compiler/lua53.can:98 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:99 +nofollowCheck[tag] = true -- ./compiler/lua53.can:100 +end -- ./compiler/lua53.can:100 +local found = {} -- ./compiler/lua53.can:102 +for _, node in ipairs(list) do -- ./compiler/lua53.can:103 +if type(node) == "table" then -- ./compiler/lua53.can:104 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:105 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:106 +table["insert"](found, n) -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:110 +table["insert"](found, node) -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +return found -- ./compiler/lua53.can:115 end -- ./compiler/lua53.can:115 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:119 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:122 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:123 -end -- ./compiler/lua53.can:123 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:125 -return "do" .. indent() -- ./compiler/lua53.can:126 -end -- ./compiler/lua53.can:126 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:128 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +local function all(list, tags) -- ./compiler/lua53.can:119 +for _, node in ipairs(list) do -- ./compiler/lua53.can:120 +local ok = false -- ./compiler/lua53.can:121 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:122 +if node["tag"] == tag then -- ./compiler/lua53.can:123 +ok = true -- ./compiler/lua53.can:124 +break -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +if not ok then -- ./compiler/lua53.can:128 +return false -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 -tags = setmetatable({ -- ./compiler/lua53.can:133 -["Block"] = function(t) -- ./compiler/lua53.can:135 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:136 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:137 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:138 -hasPush = false -- ./compiler/lua53.can:139 -end -- ./compiler/lua53.can:139 -local r = "" -- ./compiler/lua53.can:141 -if hasPush then -- ./compiler/lua53.can:142 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:143 +end -- ./compiler/lua53.can:129 +return true -- ./compiler/lua53.can:132 +end -- ./compiler/lua53.can:132 +local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:138 +local function push(name, state) -- ./compiler/lua53.can:141 +table["insert"](states[name], state) -- ./compiler/lua53.can:142 +return "" -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:145 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:146 -end -- ./compiler/lua53.can:146 -if t[# t] then -- ./compiler/lua53.can:148 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:149 -end -- ./compiler/lua53.can:149 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:151 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:152 +local function pop(name) -- ./compiler/lua53.can:146 +table["remove"](states[name]) -- ./compiler/lua53.can:147 +return "" -- ./compiler/lua53.can:148 +end -- ./compiler/lua53.can:148 +local function peek(name) -- ./compiler/lua53.can:151 +return states[name][# states[name]] -- ./compiler/lua53.can:152 end -- ./compiler/lua53.can:152 -return r -- ./compiler/lua53.can:154 -end, -- ./compiler/lua53.can:154 -["Do"] = function(t) -- ./compiler/lua53.can:160 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:161 -end, -- ./compiler/lua53.can:161 -["Set"] = function(t) -- ./compiler/lua53.can:164 -if # t == 2 then -- ./compiler/lua53.can:165 -return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:166 -elseif # t == 3 then -- ./compiler/lua53.can:167 -return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:168 -elseif # t == 4 then -- ./compiler/lua53.can:169 -if t[3] == "=" then -- ./compiler/lua53.can:170 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:171 -t[2], -- ./compiler/lua53.can:171 -t[1][1], -- ./compiler/lua53.can:171 -{ -- ./compiler/lua53.can:171 -["tag"] = "Paren", -- ./compiler/lua53.can:171 -t[4][1] -- ./compiler/lua53.can:171 -} -- ./compiler/lua53.can:171 -}, "Op") -- ./compiler/lua53.can:171 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:172 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:173 -t[2], -- ./compiler/lua53.can:173 -t[1][i], -- ./compiler/lua53.can:173 -{ -- ./compiler/lua53.can:173 -["tag"] = "Paren", -- ./compiler/lua53.can:173 -t[4][i] -- ./compiler/lua53.can:173 -} -- ./compiler/lua53.can:173 -}, "Op")) -- ./compiler/lua53.can:173 +local tags -- ./compiler/lua53.can:156 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:158 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:159 +lastInputPos = ast["pos"] -- ./compiler/lua53.can:160 +end -- ./compiler/lua53.can:160 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:162 +end -- ./compiler/lua53.can:162 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:166 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:167 +end -- ./compiler/lua53.can:167 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:169 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:170 +end -- ./compiler/lua53.can:170 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:172 +return "do" .. indent() -- ./compiler/lua53.can:173 end -- ./compiler/lua53.can:173 -return r -- ./compiler/lua53.can:175 -else -- ./compiler/lua53.can:175 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:177 -t[3], -- ./compiler/lua53.can:177 -{ -- ./compiler/lua53.can:177 -["tag"] = "Paren", -- ./compiler/lua53.can:177 -t[4][1] -- ./compiler/lua53.can:177 -}, -- ./compiler/lua53.can:177 -t[1][1] -- ./compiler/lua53.can:177 -}, "Op") -- ./compiler/lua53.can:177 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:178 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:179 -t[3], -- ./compiler/lua53.can:179 -{ -- ./compiler/lua53.can:179 -["tag"] = "Paren", -- ./compiler/lua53.can:179 -t[4][i] -- ./compiler/lua53.can:179 -}, -- ./compiler/lua53.can:179 -t[1][i] -- ./compiler/lua53.can:179 -}, "Op")) -- ./compiler/lua53.can:179 -end -- ./compiler/lua53.can:179 -return r -- ./compiler/lua53.can:181 -end -- ./compiler/lua53.can:181 -else -- ./compiler/lua53.can:181 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:184 -t[2], -- ./compiler/lua53.can:184 -t[1][1], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Op", -- ./compiler/lua53.can:184 -t[4], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Paren", -- ./compiler/lua53.can:184 -t[5][1] -- ./compiler/lua53.can:184 -}, -- ./compiler/lua53.can:184 -t[1][1] -- ./compiler/lua53.can:184 -} -- ./compiler/lua53.can:184 -}, "Op") -- ./compiler/lua53.can:184 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:185 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:186 -t[2], -- ./compiler/lua53.can:186 -t[1][i], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Op", -- ./compiler/lua53.can:186 -t[4], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Paren", -- ./compiler/lua53.can:186 -t[5][i] -- ./compiler/lua53.can:186 -}, -- ./compiler/lua53.can:186 -t[1][i] -- ./compiler/lua53.can:186 -} -- ./compiler/lua53.can:186 -}, "Op")) -- ./compiler/lua53.can:186 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:175 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:176 +end -- ./compiler/lua53.can:176 +tags = setmetatable({ -- ./compiler/lua53.can:180 +["Block"] = function(t) -- ./compiler/lua53.can:182 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:183 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:184 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:185 +hasPush = false -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -return r -- ./compiler/lua53.can:188 -end -- ./compiler/lua53.can:188 -end, -- ./compiler/lua53.can:188 -["While"] = function(t) -- ./compiler/lua53.can:192 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:193 -local r = "while " .. lua(t[1]) .. " do" .. indent() -- ./compiler/lua53.can:194 -if hasContinue then -- ./compiler/lua53.can:195 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:196 +local r = "" -- ./compiler/lua53.can:188 +if hasPush then -- ./compiler/lua53.can:189 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:190 +end -- ./compiler/lua53.can:190 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:192 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:193 +end -- ./compiler/lua53.can:193 +if t[# t] then -- ./compiler/lua53.can:195 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:196 end -- ./compiler/lua53.can:196 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:198 -if hasContinue then -- ./compiler/lua53.can:199 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:200 -end -- ./compiler/lua53.can:200 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:202 -return r -- ./compiler/lua53.can:203 -end, -- ./compiler/lua53.can:203 -["Repeat"] = function(t) -- ./compiler/lua53.can:206 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:207 -local r = "repeat" .. indent() -- ./compiler/lua53.can:208 -if hasContinue then -- ./compiler/lua53.can:209 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:210 -end -- ./compiler/lua53.can:210 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:212 -if hasContinue then -- ./compiler/lua53.can:213 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:216 -return r -- ./compiler/lua53.can:217 -end, -- ./compiler/lua53.can:217 -["If"] = function(t) -- ./compiler/lua53.can:220 -local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() -- ./compiler/lua53.can:221 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:222 -r = r .. ("elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:223 -end -- ./compiler/lua53.can:223 -if # t % 2 == 1 then -- ./compiler/lua53.can:225 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:226 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:198 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:199 +end -- ./compiler/lua53.can:199 +return r -- ./compiler/lua53.can:201 +end, -- ./compiler/lua53.can:201 +["Do"] = function(t) -- ./compiler/lua53.can:207 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:208 +end, -- ./compiler/lua53.can:208 +["Set"] = function(t) -- ./compiler/lua53.can:211 +if # t == 2 then -- ./compiler/lua53.can:212 +return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:213 +elseif # t == 3 then -- ./compiler/lua53.can:214 +return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:215 +elseif # t == 4 then -- ./compiler/lua53.can:216 +if t[3] == "=" then -- ./compiler/lua53.can:217 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:218 +t[2], -- ./compiler/lua53.can:218 +t[1][1], -- ./compiler/lua53.can:218 +{ -- ./compiler/lua53.can:218 +["tag"] = "Paren", -- ./compiler/lua53.can:218 +t[4][1] -- ./compiler/lua53.can:218 +} -- ./compiler/lua53.can:218 +}, "Op") -- ./compiler/lua53.can:218 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:219 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:220 +t[2], -- ./compiler/lua53.can:220 +t[1][i], -- ./compiler/lua53.can:220 +{ -- ./compiler/lua53.can:220 +["tag"] = "Paren", -- ./compiler/lua53.can:220 +t[4][i] -- ./compiler/lua53.can:220 +} -- ./compiler/lua53.can:220 +}, "Op")) -- ./compiler/lua53.can:220 +end -- ./compiler/lua53.can:220 +return r -- ./compiler/lua53.can:222 +else -- ./compiler/lua53.can:222 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:224 +t[3], -- ./compiler/lua53.can:224 +{ -- ./compiler/lua53.can:224 +["tag"] = "Paren", -- ./compiler/lua53.can:224 +t[4][1] -- ./compiler/lua53.can:224 +}, -- ./compiler/lua53.can:224 +t[1][1] -- ./compiler/lua53.can:224 +}, "Op") -- ./compiler/lua53.can:224 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:225 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:226 +t[3], -- ./compiler/lua53.can:226 +{ -- ./compiler/lua53.can:226 +["tag"] = "Paren", -- ./compiler/lua53.can:226 +t[4][i] -- ./compiler/lua53.can:226 +}, -- ./compiler/lua53.can:226 +t[1][i] -- ./compiler/lua53.can:226 +}, "Op")) -- ./compiler/lua53.can:226 end -- ./compiler/lua53.can:226 -return r .. "end" -- ./compiler/lua53.can:228 -end, -- ./compiler/lua53.can:228 -["Fornum"] = function(t) -- ./compiler/lua53.can:231 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:232 -if # t == 5 then -- ./compiler/lua53.can:233 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:234 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:235 -if hasContinue then -- ./compiler/lua53.can:236 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:237 -end -- ./compiler/lua53.can:237 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:239 -if hasContinue then -- ./compiler/lua53.can:240 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:241 -end -- ./compiler/lua53.can:241 -return r .. unindent() .. "end" -- ./compiler/lua53.can:243 -else -- ./compiler/lua53.can:243 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:245 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:246 -if hasContinue then -- ./compiler/lua53.can:247 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:248 -end -- ./compiler/lua53.can:248 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:250 -if hasContinue then -- ./compiler/lua53.can:251 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. unindent() .. "end" -- ./compiler/lua53.can:254 +return r -- ./compiler/lua53.can:228 +end -- ./compiler/lua53.can:228 +else -- ./compiler/lua53.can:228 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:231 +t[2], -- ./compiler/lua53.can:231 +t[1][1], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Op", -- ./compiler/lua53.can:231 +t[4], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Paren", -- ./compiler/lua53.can:231 +t[5][1] -- ./compiler/lua53.can:231 +}, -- ./compiler/lua53.can:231 +t[1][1] -- ./compiler/lua53.can:231 +} -- ./compiler/lua53.can:231 +}, "Op") -- ./compiler/lua53.can:231 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:232 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:233 +t[2], -- ./compiler/lua53.can:233 +t[1][i], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Op", -- ./compiler/lua53.can:233 +t[4], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Paren", -- ./compiler/lua53.can:233 +t[5][i] -- ./compiler/lua53.can:233 +}, -- ./compiler/lua53.can:233 +t[1][i] -- ./compiler/lua53.can:233 +} -- ./compiler/lua53.can:233 +}, "Op")) -- ./compiler/lua53.can:233 +end -- ./compiler/lua53.can:233 +return r -- ./compiler/lua53.can:235 +end -- ./compiler/lua53.can:235 +end, -- ./compiler/lua53.can:235 +["While"] = function(t) -- ./compiler/lua53.can:239 +local r = "" -- ./compiler/lua53.can:240 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:241 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:242 +if # lets > 0 then -- ./compiler/lua53.can:243 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:244 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:245 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:249 +if # lets > 0 then -- ./compiler/lua53.can:250 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:251 +end -- ./compiler/lua53.can:251 +if hasContinue then -- ./compiler/lua53.can:253 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:254 end -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Forin"] = function(t) -- ./compiler/lua53.can:258 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:259 -local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:260 -if hasContinue then -- ./compiler/lua53.can:261 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:262 -end -- ./compiler/lua53.can:262 -r = r .. (lua(t[3])) -- ./compiler/lua53.can:264 -if hasContinue then -- ./compiler/lua53.can:265 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:266 -end -- ./compiler/lua53.can:266 -return r .. unindent() .. "end" -- ./compiler/lua53.can:268 -end, -- ./compiler/lua53.can:268 -["Local"] = function(t) -- ./compiler/lua53.can:271 -local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:272 -if t[2][1] then -- ./compiler/lua53.can:273 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:274 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:256 +if hasContinue then -- ./compiler/lua53.can:257 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:258 +end -- ./compiler/lua53.can:258 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:260 +if # lets > 0 then -- ./compiler/lua53.can:261 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:262 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:263 +end -- ./compiler/lua53.can:263 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:265 +end -- ./compiler/lua53.can:265 +return r -- ./compiler/lua53.can:267 +end, -- ./compiler/lua53.can:267 +["Repeat"] = function(t) -- ./compiler/lua53.can:270 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:271 +local r = "repeat" .. indent() -- ./compiler/lua53.can:272 +if hasContinue then -- ./compiler/lua53.can:273 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:274 end -- ./compiler/lua53.can:274 -return r -- ./compiler/lua53.can:276 -end, -- ./compiler/lua53.can:276 -["Let"] = function(t) -- ./compiler/lua53.can:279 -local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:280 -local r = "local " .. nameList -- ./compiler/lua53.can:281 -if t[2][1] then -- ./compiler/lua53.can:282 -if any(t[2], { -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Function", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Table", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Paren" -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -}) then -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:284 -else -- ./compiler/lua53.can:284 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -return r -- ./compiler/lua53.can:289 -end, -- ./compiler/lua53.can:289 -["Localrec"] = function(t) -- ./compiler/lua53.can:292 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:293 -end, -- ./compiler/lua53.can:293 -["Goto"] = function(t) -- ./compiler/lua53.can:296 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:297 -end, -- ./compiler/lua53.can:297 -["Label"] = function(t) -- ./compiler/lua53.can:300 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:301 -end, -- ./compiler/lua53.can:301 -["Return"] = function(t) -- ./compiler/lua53.can:304 -local push = peek("push") -- ./compiler/lua53.can:305 -if push then -- ./compiler/lua53.can:306 -local r = "" -- ./compiler/lua53.can:307 -for _, val in ipairs(t) do -- ./compiler/lua53.can:308 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:309 -end -- ./compiler/lua53.can:309 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:311 -else -- ./compiler/lua53.can:311 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:313 -end -- ./compiler/lua53.can:313 -end, -- ./compiler/lua53.can:313 -["Push"] = function(t) -- ./compiler/lua53.can:317 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:318 -r = "" -- ./compiler/lua53.can:319 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:320 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:321 -end -- ./compiler/lua53.can:321 -if t[# t] then -- ./compiler/lua53.can:323 -if t[# t]["tag"] == "Call" or t[# t]["tag"] == "Invoke" then -- ./compiler/lua53.can:324 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:325 -else -- ./compiler/lua53.can:325 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -return r -- ./compiler/lua53.can:330 -end, -- ./compiler/lua53.can:330 -["Break"] = function() -- ./compiler/lua53.can:333 -return "break" -- ./compiler/lua53.can:334 -end, -- ./compiler/lua53.can:334 -["Continue"] = function() -- ./compiler/lua53.can:337 -return "goto " .. var("continue") -- ./compiler/lua53.can:338 -end, -- ./compiler/lua53.can:338 -["Nil"] = function() -- ./compiler/lua53.can:345 -return "nil" -- ./compiler/lua53.can:346 -end, -- ./compiler/lua53.can:346 -["Dots"] = function() -- ./compiler/lua53.can:349 -return "..." -- ./compiler/lua53.can:350 -end, -- ./compiler/lua53.can:350 -["Boolean"] = function(t) -- ./compiler/lua53.can:353 -return tostring(t[1]) -- ./compiler/lua53.can:354 -end, -- ./compiler/lua53.can:354 -["Number"] = function(t) -- ./compiler/lua53.can:357 -return tostring(t[1]) -- ./compiler/lua53.can:358 -end, -- ./compiler/lua53.can:358 -["String"] = function(t) -- ./compiler/lua53.can:361 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:362 -end, -- ./compiler/lua53.can:362 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:365 -local r = "(" -- ./compiler/lua53.can:366 -local decl = {} -- ./compiler/lua53.can:367 -if t[1][1] then -- ./compiler/lua53.can:368 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:369 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:370 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:371 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:372 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:373 -r = r .. (id) -- ./compiler/lua53.can:374 -else -- ./compiler/lua53.can:374 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:378 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:379 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:380 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:381 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:382 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:383 -r = r .. (", " .. id) -- ./compiler/lua53.can:384 -else -- ./compiler/lua53.can:384 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:390 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:391 -r = r .. (d .. newline()) -- ./compiler/lua53.can:392 -end -- ./compiler/lua53.can:392 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:394 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:395 -end -- ./compiler/lua53.can:395 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:397 -if hasPush then -- ./compiler/lua53.can:398 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:399 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:276 +if hasContinue then -- ./compiler/lua53.can:277 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:278 +end -- ./compiler/lua53.can:278 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:280 +return r -- ./compiler/lua53.can:281 +end, -- ./compiler/lua53.can:281 +["If"] = function(t) -- ./compiler/lua53.can:284 +local r = "" -- ./compiler/lua53.can:285 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:286 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:287 +if # lets > 0 then -- ./compiler/lua53.can:288 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:289 +toClose = toClose + (1) -- ./compiler/lua53.can:290 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:291 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:295 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:296 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:297 +if # lets > 0 then -- ./compiler/lua53.can:298 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:299 +toClose = toClose + (1) -- ./compiler/lua53.can:300 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:301 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:302 +end -- ./compiler/lua53.can:302 +else -- ./compiler/lua53.can:302 +r = r .. ("else") -- ./compiler/lua53.can:305 +end -- ./compiler/lua53.can:305 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:307 +end -- ./compiler/lua53.can:307 +if # t % 2 == 1 then -- ./compiler/lua53.can:309 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:310 +end -- ./compiler/lua53.can:310 +r = r .. ("end") -- ./compiler/lua53.can:312 +for i = 1, toClose do -- ./compiler/lua53.can:313 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:314 +end -- ./compiler/lua53.can:314 +return r -- ./compiler/lua53.can:316 +end, -- ./compiler/lua53.can:316 +["Fornum"] = function(t) -- ./compiler/lua53.can:319 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:320 +if # t == 5 then -- ./compiler/lua53.can:321 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:322 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:323 +if hasContinue then -- ./compiler/lua53.can:324 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:325 +end -- ./compiler/lua53.can:325 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:327 +if hasContinue then -- ./compiler/lua53.can:328 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:329 +end -- ./compiler/lua53.can:329 +return r .. unindent() .. "end" -- ./compiler/lua53.can:331 +else -- ./compiler/lua53.can:331 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:333 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:334 +if hasContinue then -- ./compiler/lua53.can:335 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:336 +end -- ./compiler/lua53.can:336 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:338 +if hasContinue then -- ./compiler/lua53.can:339 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:340 +end -- ./compiler/lua53.can:340 +return r .. unindent() .. "end" -- ./compiler/lua53.can:342 +end -- ./compiler/lua53.can:342 +end, -- ./compiler/lua53.can:342 +["Forin"] = function(t) -- ./compiler/lua53.can:346 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:347 +local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:348 +if hasContinue then -- ./compiler/lua53.can:349 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:350 +end -- ./compiler/lua53.can:350 +r = r .. (lua(t[3])) -- ./compiler/lua53.can:352 +if hasContinue then -- ./compiler/lua53.can:353 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:354 +end -- ./compiler/lua53.can:354 +return r .. unindent() .. "end" -- ./compiler/lua53.can:356 +end, -- ./compiler/lua53.can:356 +["Local"] = function(t) -- ./compiler/lua53.can:359 +local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:360 +if t[2][1] then -- ./compiler/lua53.can:361 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:362 +end -- ./compiler/lua53.can:362 +return r -- ./compiler/lua53.can:364 +end, -- ./compiler/lua53.can:364 +["Let"] = function(t) -- ./compiler/lua53.can:367 +local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:368 +local r = "local " .. nameList -- ./compiler/lua53.can:369 +if t[2][1] then -- ./compiler/lua53.can:370 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:372 +else -- ./compiler/lua53.can:372 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +return r -- ./compiler/lua53.can:377 +end, -- ./compiler/lua53.can:377 +["Localrec"] = function(t) -- ./compiler/lua53.can:380 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:381 +end, -- ./compiler/lua53.can:381 +["Goto"] = function(t) -- ./compiler/lua53.can:384 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:385 +end, -- ./compiler/lua53.can:385 +["Label"] = function(t) -- ./compiler/lua53.can:388 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:389 +end, -- ./compiler/lua53.can:389 +["Return"] = function(t) -- ./compiler/lua53.can:392 +local push = peek("push") -- ./compiler/lua53.can:393 +if push then -- ./compiler/lua53.can:394 +local r = "" -- ./compiler/lua53.can:395 +for _, val in ipairs(t) do -- ./compiler/lua53.can:396 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:397 +end -- ./compiler/lua53.can:397 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:399 else -- ./compiler/lua53.can:399 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:403 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:404 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -pop("push") -- ./compiler/lua53.can:407 -return r .. unindent() .. "end" -- ./compiler/lua53.can:408 -end, -- ./compiler/lua53.can:408 -["Function"] = function(t) -- ./compiler/lua53.can:410 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:411 -end, -- ./compiler/lua53.can:411 -["Pair"] = function(t) -- ./compiler/lua53.can:414 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:415 -end, -- ./compiler/lua53.can:415 -["Table"] = function(t) -- ./compiler/lua53.can:417 -if # t == 0 then -- ./compiler/lua53.can:418 -return "{}" -- ./compiler/lua53.can:419 -elseif # t == 1 then -- ./compiler/lua53.can:420 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:421 -else -- ./compiler/lua53.can:421 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -end, -- ./compiler/lua53.can:423 -["TableCompr"] = function(t) -- ./compiler/lua53.can:427 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:428 -end, -- ./compiler/lua53.can:428 -["Op"] = function(t) -- ./compiler/lua53.can:431 -local r -- ./compiler/lua53.can:432 -if # t == 2 then -- ./compiler/lua53.can:433 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:434 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:435 -else -- ./compiler/lua53.can:435 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:437 -end -- ./compiler/lua53.can:437 -else -- ./compiler/lua53.can:437 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:440 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:441 -else -- ./compiler/lua53.can:441 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -return r -- ./compiler/lua53.can:446 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:401 +end -- ./compiler/lua53.can:401 +end, -- ./compiler/lua53.can:401 +["Push"] = function(t) -- ./compiler/lua53.can:405 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:406 +r = "" -- ./compiler/lua53.can:407 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:408 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:409 +end -- ./compiler/lua53.can:409 +if t[# t] then -- ./compiler/lua53.can:411 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:412 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:413 +else -- ./compiler/lua53.can:413 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +return r -- ./compiler/lua53.can:418 +end, -- ./compiler/lua53.can:418 +["Break"] = function() -- ./compiler/lua53.can:421 +return "break" -- ./compiler/lua53.can:422 +end, -- ./compiler/lua53.can:422 +["Continue"] = function() -- ./compiler/lua53.can:425 +return "goto " .. var("continue") -- ./compiler/lua53.can:426 +end, -- ./compiler/lua53.can:426 +["Nil"] = function() -- ./compiler/lua53.can:433 +return "nil" -- ./compiler/lua53.can:434 +end, -- ./compiler/lua53.can:434 +["Dots"] = function() -- ./compiler/lua53.can:437 +return "..." -- ./compiler/lua53.can:438 +end, -- ./compiler/lua53.can:438 +["Boolean"] = function(t) -- ./compiler/lua53.can:441 +return tostring(t[1]) -- ./compiler/lua53.can:442 +end, -- ./compiler/lua53.can:442 +["Number"] = function(t) -- ./compiler/lua53.can:445 +return tostring(t[1]) -- ./compiler/lua53.can:446 end, -- ./compiler/lua53.can:446 -["Paren"] = function(t) -- ./compiler/lua53.can:449 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:450 +["String"] = function(t) -- ./compiler/lua53.can:449 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 end, -- ./compiler/lua53.can:450 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:457 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:458 -local r = "(function()" .. indent() -- ./compiler/lua53.can:459 -if hasPush then -- ./compiler/lua53.can:460 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:461 -else -- ./compiler/lua53.can:461 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:465 -if hasPush then -- ./compiler/lua53.can:466 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:467 -end -- ./compiler/lua53.can:467 -pop("push") -- ./compiler/lua53.can:469 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:470 -return r -- ./compiler/lua53.can:471 -end, -- ./compiler/lua53.can:471 -["DoExpr"] = function(t) -- ./compiler/lua53.can:474 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:475 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:476 -end -- ./compiler/lua53.can:476 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:481 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:485 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["IfExpr"] = function(t) -- ./compiler/lua53.can:489 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:490 -local block = t[i] -- ./compiler/lua53.can:491 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:492 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:493 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:453 +local r = "(" -- ./compiler/lua53.can:454 +local decl = {} -- ./compiler/lua53.can:455 +if t[1][1] then -- ./compiler/lua53.can:456 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:457 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:458 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:459 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:460 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:461 +r = r .. (id) -- ./compiler/lua53.can:462 +else -- ./compiler/lua53.can:462 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:464 +end -- ./compiler/lua53.can:464 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:466 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:467 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:468 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:469 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:470 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:471 +r = r .. (", " .. id) -- ./compiler/lua53.can:472 +else -- ./compiler/lua53.can:472 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:478 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:479 +r = r .. (d .. newline()) -- ./compiler/lua53.can:480 +end -- ./compiler/lua53.can:480 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:482 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:483 +end -- ./compiler/lua53.can:483 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:485 +if hasPush then -- ./compiler/lua53.can:486 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:487 +else -- ./compiler/lua53.can:487 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:491 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:492 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:493 end -- ./compiler/lua53.can:493 -end -- ./compiler/lua53.can:493 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:496 +pop("push") -- ./compiler/lua53.can:495 +return r .. unindent() .. "end" -- ./compiler/lua53.can:496 end, -- ./compiler/lua53.can:496 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:499 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:500 -end, -- ./compiler/lua53.can:500 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:503 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:504 -end, -- ./compiler/lua53.can:504 -["Call"] = function(t) -- ./compiler/lua53.can:510 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:511 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:512 -else -- ./compiler/lua53.can:512 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:514 -end -- ./compiler/lua53.can:514 -end, -- ./compiler/lua53.can:514 -["Invoke"] = function(t) -- ./compiler/lua53.can:519 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:520 -return "(" .. lua(t[1]) .. "):" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:521 -else -- ./compiler/lua53.can:521 -return lua(t[1]) .. ":" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:523 -end -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:528 -if start == nil then start = 1 end -- ./compiler/lua53.can:528 -local r -- ./compiler/lua53.can:529 -if t[start] then -- ./compiler/lua53.can:530 -r = lua(t[start]) -- ./compiler/lua53.can:531 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:532 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:533 -end -- ./compiler/lua53.can:533 -else -- ./compiler/lua53.can:533 -r = "" -- ./compiler/lua53.can:536 -end -- ./compiler/lua53.can:536 -return r -- ./compiler/lua53.can:538 +["Function"] = function(t) -- ./compiler/lua53.can:498 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:499 +end, -- ./compiler/lua53.can:499 +["Pair"] = function(t) -- ./compiler/lua53.can:502 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:503 +end, -- ./compiler/lua53.can:503 +["Table"] = function(t) -- ./compiler/lua53.can:505 +if # t == 0 then -- ./compiler/lua53.can:506 +return "{}" -- ./compiler/lua53.can:507 +elseif # t == 1 then -- ./compiler/lua53.can:508 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:509 +else -- ./compiler/lua53.can:509 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:511 +end -- ./compiler/lua53.can:511 +end, -- ./compiler/lua53.can:511 +["TableCompr"] = function(t) -- ./compiler/lua53.can:515 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:516 +end, -- ./compiler/lua53.can:516 +["Op"] = function(t) -- ./compiler/lua53.can:519 +local r -- ./compiler/lua53.can:520 +if # t == 2 then -- ./compiler/lua53.can:521 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:522 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:523 +else -- ./compiler/lua53.can:523 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:525 +end -- ./compiler/lua53.can:525 +else -- ./compiler/lua53.can:525 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:528 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:529 +else -- ./compiler/lua53.can:529 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +return r -- ./compiler/lua53.can:534 +end, -- ./compiler/lua53.can:534 +["Paren"] = function(t) -- ./compiler/lua53.can:537 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:538 end, -- ./compiler/lua53.can:538 -["Id"] = function(t) -- ./compiler/lua53.can:541 -return t[1] -- ./compiler/lua53.can:542 -end, -- ./compiler/lua53.can:542 -["Index"] = function(t) -- ./compiler/lua53.can:545 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:546 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:547 -else -- ./compiler/lua53.can:547 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:549 -end -- ./compiler/lua53.can:549 -end, -- ./compiler/lua53.can:549 -["_opid"] = { -- ./compiler/lua53.can:554 -["add"] = "+", -- ./compiler/lua53.can:555 -["sub"] = "-", -- ./compiler/lua53.can:555 -["mul"] = "*", -- ./compiler/lua53.can:555 -["div"] = "/", -- ./compiler/lua53.can:555 -["idiv"] = "//", -- ./compiler/lua53.can:556 -["mod"] = "%", -- ./compiler/lua53.can:556 -["pow"] = "^", -- ./compiler/lua53.can:556 -["concat"] = "..", -- ./compiler/lua53.can:556 -["band"] = "&", -- ./compiler/lua53.can:557 -["bor"] = "|", -- ./compiler/lua53.can:557 -["bxor"] = "~", -- ./compiler/lua53.can:557 -["shl"] = "<<", -- ./compiler/lua53.can:557 -["shr"] = ">>", -- ./compiler/lua53.can:557 -["eq"] = "==", -- ./compiler/lua53.can:558 -["ne"] = "~=", -- ./compiler/lua53.can:558 -["lt"] = "<", -- ./compiler/lua53.can:558 -["gt"] = ">", -- ./compiler/lua53.can:558 -["le"] = "<=", -- ./compiler/lua53.can:558 -["ge"] = ">=", -- ./compiler/lua53.can:558 -["and"] = "and", -- ./compiler/lua53.can:559 -["or"] = "or", -- ./compiler/lua53.can:559 -["unm"] = "-", -- ./compiler/lua53.can:559 -["len"] = "#", -- ./compiler/lua53.can:559 -["bnot"] = "~", -- ./compiler/lua53.can:559 -["not"] = "not" -- ./compiler/lua53.can:559 -} -- ./compiler/lua53.can:559 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:562 -error("don't know how to compile a " .. tostring(key) .. " to Lua 5.3") -- ./compiler/lua53.can:563 -end }) -- ./compiler/lua53.can:563 -local code = lua(ast) .. newline() -- ./compiler/lua53.can:569 -return requireStr .. code -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -local lua53 = _() or lua53 -- ./compiler/lua53.can:575 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:576 -local function _() -- ./compiler/lua53.can:579 -local function _() -- ./compiler/lua53.can:581 -return function(code, ast, options) -- ./compiler/lua53.can:1 -local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:3 -local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:4 -local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:5 -local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:6 -local indentLevel = 0 -- ./compiler/lua53.can:9 -local function newline() -- ./compiler/lua53.can:11 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:12 -if options["mapLines"] then -- ./compiler/lua53.can:13 -local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:14 +["MethodStub"] = function(t) -- ./compiler/lua53.can:541 +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/lua53.can:547 +end, -- ./compiler/lua53.can:547 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:550 +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/lua53.can:557 +end, -- ./compiler/lua53.can:557 +["LetExpr"] = function(t) -- ./compiler/lua53.can:564 +return lua(t[1][1]) -- ./compiler/lua53.can:565 +end, -- ./compiler/lua53.can:565 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:569 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:570 +local r = "(function()" .. indent() -- ./compiler/lua53.can:571 +if hasPush then -- ./compiler/lua53.can:572 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:573 +else -- ./compiler/lua53.can:573 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:577 +if hasPush then -- ./compiler/lua53.can:578 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:579 +end -- ./compiler/lua53.can:579 +pop("push") -- ./compiler/lua53.can:581 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:582 +return r -- ./compiler/lua53.can:583 +end, -- ./compiler/lua53.can:583 +["DoExpr"] = function(t) -- ./compiler/lua53.can:586 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:587 +t[# t]["tag"] = "Return" -- ./compiler/lua53.can:588 +end -- ./compiler/lua53.can:588 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:590 +end, -- ./compiler/lua53.can:590 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:593 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:594 +end, -- ./compiler/lua53.can:594 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:597 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:598 +end, -- ./compiler/lua53.can:598 +["IfExpr"] = function(t) -- ./compiler/lua53.can:601 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:602 +local block = t[i] -- ./compiler/lua53.can:603 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:604 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:608 +end, -- ./compiler/lua53.can:608 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:611 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:612 +end, -- ./compiler/lua53.can:612 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:615 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:616 +end, -- ./compiler/lua53.can:616 +["Call"] = function(t) -- ./compiler/lua53.can:622 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:623 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:624 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:625 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:626 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:627 +else -- ./compiler/lua53.can:627 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:629 +end -- ./compiler/lua53.can:629 +else -- ./compiler/lua53.can:629 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:632 +end -- ./compiler/lua53.can:632 +end, -- ./compiler/lua53.can:632 +["SafeCall"] = function(t) -- ./compiler/lua53.can:636 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:637 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:638 +else -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:640 +end -- ./compiler/lua53.can:640 +end, -- ./compiler/lua53.can:640 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:645 +if start == nil then start = 1 end -- ./compiler/lua53.can:645 +local r -- ./compiler/lua53.can:646 +if t[start] then -- ./compiler/lua53.can:647 +r = lua(t[start]) -- ./compiler/lua53.can:648 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:649 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:650 +end -- ./compiler/lua53.can:650 +else -- ./compiler/lua53.can:650 +r = "" -- ./compiler/lua53.can:653 +end -- ./compiler/lua53.can:653 +return r -- ./compiler/lua53.can:655 +end, -- ./compiler/lua53.can:655 +["Id"] = function(t) -- ./compiler/lua53.can:658 +return t[1] -- ./compiler/lua53.can:659 +end, -- ./compiler/lua53.can:659 +["Index"] = function(t) -- ./compiler/lua53.can:662 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:663 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:664 +else -- ./compiler/lua53.can:664 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:666 +end -- ./compiler/lua53.can:666 +end, -- ./compiler/lua53.can:666 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:670 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:671 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:672 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:673 +table["insert"](l, 1, t) -- ./compiler/lua53.can:674 +t = t[1] -- ./compiler/lua53.can:675 +end -- ./compiler/lua53.can:675 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:677 +for _, e in ipairs(l) do -- ./compiler/lua53.can:678 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:679 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:680 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:681 +else -- ./compiler/lua53.can:681 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:686 +return r -- ./compiler/lua53.can:687 +else -- ./compiler/lua53.can:687 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:689 +end -- ./compiler/lua53.can:689 +end, -- ./compiler/lua53.can:689 +["_opid"] = { -- ./compiler/lua53.can:694 +["add"] = "+", -- ./compiler/lua53.can:695 +["sub"] = "-", -- ./compiler/lua53.can:695 +["mul"] = "*", -- ./compiler/lua53.can:695 +["div"] = "/", -- ./compiler/lua53.can:695 +["idiv"] = "//", -- ./compiler/lua53.can:696 +["mod"] = "%", -- ./compiler/lua53.can:696 +["pow"] = "^", -- ./compiler/lua53.can:696 +["concat"] = "..", -- ./compiler/lua53.can:696 +["band"] = "&", -- ./compiler/lua53.can:697 +["bor"] = "|", -- ./compiler/lua53.can:697 +["bxor"] = "~", -- ./compiler/lua53.can:697 +["shl"] = "<<", -- ./compiler/lua53.can:697 +["shr"] = ">>", -- ./compiler/lua53.can:697 +["eq"] = "==", -- ./compiler/lua53.can:698 +["ne"] = "~=", -- ./compiler/lua53.can:698 +["lt"] = "<", -- ./compiler/lua53.can:698 +["gt"] = ">", -- ./compiler/lua53.can:698 +["le"] = "<=", -- ./compiler/lua53.can:698 +["ge"] = ">=", -- ./compiler/lua53.can:698 +["and"] = "and", -- ./compiler/lua53.can:699 +["or"] = "or", -- ./compiler/lua53.can:699 +["unm"] = "-", -- ./compiler/lua53.can:699 +["len"] = "#", -- ./compiler/lua53.can:699 +["bnot"] = "~", -- ./compiler/lua53.can:699 +["not"] = "not" -- ./compiler/lua53.can:699 +} -- ./compiler/lua53.can:699 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:702 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:703 +end }) -- ./compiler/lua53.can:703 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:709 +return requireStr .. code -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +local lua53 = _() or lua53 -- ./compiler/lua53.can:715 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:716 +local function _() -- ./compiler/lua53.can:719 +local function _() -- ./compiler/lua53.can:721 +local targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +return function(code, ast, options) -- ./compiler/lua53.can:3 +local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:7 +local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:8 +local indentLevel = 0 -- ./compiler/lua53.can:11 +local function newline() -- ./compiler/lua53.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:14 +if options["mapLines"] then -- ./compiler/lua53.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:16 local source, line = sub:sub(1, sub:find("\ ")):match("%-%- (.-)%:(%d+)\ -") -- ./compiler/lua53.can:15 -if source and line then -- ./compiler/lua53.can:17 -lastSource = source -- ./compiler/lua53.can:18 -lastLine = tonumber(line) -- ./compiler/lua53.can:19 -else -- ./compiler/lua53.can:19 +") -- ./compiler/lua53.can:17 +if source and line then -- ./compiler/lua53.can:19 +lastSource = source -- ./compiler/lua53.can:20 +lastLine = tonumber(line) -- ./compiler/lua53.can:21 +else -- ./compiler/lua53.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua53.can:21 -lastLine = lastLine + (1) -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -prevLinePos = lastInputPos -- ./compiler/lua53.can:26 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:28 -end -- ./compiler/lua53.can:28 -return r -- ./compiler/lua53.can:30 +") do -- ./compiler/lua53.can:23 +lastLine = lastLine + (1) -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +prevLinePos = lastInputPos -- ./compiler/lua53.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:30 end -- ./compiler/lua53.can:30 -local function indent() -- ./compiler/lua53.can:33 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:34 -return newline() -- ./compiler/lua53.can:35 -end -- ./compiler/lua53.can:35 -local function unindent() -- ./compiler/lua53.can:38 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:39 -return newline() -- ./compiler/lua53.can:40 -end -- ./compiler/lua53.can:40 -local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:44 -local requireStr = "" -- ./compiler/lua53.can:45 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:47 -if not required[mod] then -- ./compiler/lua53.can:48 -requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:49 -required[mod] = true -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -local function var(name) -- ./compiler/lua53.can:56 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:57 -end -- ./compiler/lua53.can:57 -local loop = { -- loops tags -- ./compiler/lua53.can:61 -"While", -- loops tags -- ./compiler/lua53.can:61 -"Repeat", -- loops tags -- ./compiler/lua53.can:61 -"Fornum", -- loops tags -- ./compiler/lua53.can:61 -"Forin" -- loops tags -- ./compiler/lua53.can:61 -} -- loops tags -- ./compiler/lua53.can:61 -local func = { -- function scope tags -- ./compiler/lua53.can:62 -"Function", -- function scope tags -- ./compiler/lua53.can:62 -"TableCompr", -- function scope tags -- ./compiler/lua53.can:62 -"DoExpr", -- function scope tags -- ./compiler/lua53.can:62 -"WhileExpr", -- function scope tags -- ./compiler/lua53.can:62 -"RepeatExpr", -- function scope tags -- ./compiler/lua53.can:62 -"IfExpr", -- function scope tags -- ./compiler/lua53.can:62 -"FornumExpr", -- function scope tags -- ./compiler/lua53.can:62 -"ForinExpr" -- function scope tags -- ./compiler/lua53.can:62 -} -- function scope tags -- ./compiler/lua53.can:62 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:65 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:65 -local tagsCheck = {} -- ./compiler/lua53.can:66 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:67 -tagsCheck[tag] = true -- ./compiler/lua53.can:68 -end -- ./compiler/lua53.can:68 -local nofollowCheck = {} -- ./compiler/lua53.can:70 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:71 -nofollowCheck[tag] = true -- ./compiler/lua53.can:72 -end -- ./compiler/lua53.can:72 -for _, node in ipairs(list) do -- ./compiler/lua53.can:74 -if type(node) == "table" then -- ./compiler/lua53.can:75 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:76 -return node -- ./compiler/lua53.can:77 -end -- ./compiler/lua53.can:77 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:79 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:80 -if r then -- ./compiler/lua53.can:81 -return r -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -return nil -- ./compiler/lua53.can:85 -end -- ./compiler/lua53.can:85 -local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:91 -local function push(name, state) -- ./compiler/lua53.can:94 -table["insert"](states[name], state) -- ./compiler/lua53.can:95 -return "" -- ./compiler/lua53.can:96 +return r -- ./compiler/lua53.can:32 +end -- ./compiler/lua53.can:32 +local function indent() -- ./compiler/lua53.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:36 +return newline() -- ./compiler/lua53.can:37 +end -- ./compiler/lua53.can:37 +local function unindent() -- ./compiler/lua53.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 +return newline() -- ./compiler/lua53.can:42 +end -- ./compiler/lua53.can:42 +local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:46 +local requireStr = "" -- ./compiler/lua53.can:47 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:49 +if not required[mod] then -- ./compiler/lua53.can:50 +requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:51 +required[mod] = true -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +local function var(name) -- ./compiler/lua53.can:58 +return options["variablePrefix"] .. name -- ./compiler/lua53.can:59 +end -- ./compiler/lua53.can:59 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:68 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:68 +local tagsCheck = {} -- ./compiler/lua53.can:69 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:70 +tagsCheck[tag] = true -- ./compiler/lua53.can:71 +end -- ./compiler/lua53.can:71 +local nofollowCheck = {} -- ./compiler/lua53.can:73 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:74 +nofollowCheck[tag] = true -- ./compiler/lua53.can:75 +end -- ./compiler/lua53.can:75 +for _, node in ipairs(list) do -- ./compiler/lua53.can:77 +if type(node) == "table" then -- ./compiler/lua53.can:78 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:79 +return node -- ./compiler/lua53.can:80 +end -- ./compiler/lua53.can:80 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:82 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:83 +if r then -- ./compiler/lua53.can:84 +return r -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +return nil -- ./compiler/lua53.can:88 +end -- ./compiler/lua53.can:88 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:93 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:93 +local tagsCheck = {} -- ./compiler/lua53.can:94 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:95 +tagsCheck[tag] = true -- ./compiler/lua53.can:96 end -- ./compiler/lua53.can:96 -local function pop(name) -- ./compiler/lua53.can:99 -table["remove"](states[name]) -- ./compiler/lua53.can:100 -return "" -- ./compiler/lua53.can:101 -end -- ./compiler/lua53.can:101 -local function peek(name) -- ./compiler/lua53.can:104 -return states[name][# states[name]] -- ./compiler/lua53.can:105 -end -- ./compiler/lua53.can:105 -local tags -- ./compiler/lua53.can:109 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:111 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:112 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:113 -end -- ./compiler/lua53.can:113 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:115 +local nofollowCheck = {} -- ./compiler/lua53.can:98 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:99 +nofollowCheck[tag] = true -- ./compiler/lua53.can:100 +end -- ./compiler/lua53.can:100 +local found = {} -- ./compiler/lua53.can:102 +for _, node in ipairs(list) do -- ./compiler/lua53.can:103 +if type(node) == "table" then -- ./compiler/lua53.can:104 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:105 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:106 +table["insert"](found, n) -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:110 +table["insert"](found, node) -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +return found -- ./compiler/lua53.can:115 end -- ./compiler/lua53.can:115 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:119 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:122 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:123 -end -- ./compiler/lua53.can:123 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:125 -return "do" .. indent() -- ./compiler/lua53.can:126 -end -- ./compiler/lua53.can:126 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:128 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +local function all(list, tags) -- ./compiler/lua53.can:119 +for _, node in ipairs(list) do -- ./compiler/lua53.can:120 +local ok = false -- ./compiler/lua53.can:121 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:122 +if node["tag"] == tag then -- ./compiler/lua53.can:123 +ok = true -- ./compiler/lua53.can:124 +break -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +if not ok then -- ./compiler/lua53.can:128 +return false -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 -tags = setmetatable({ -- ./compiler/lua53.can:133 -["Block"] = function(t) -- ./compiler/lua53.can:135 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:136 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:137 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:138 -hasPush = false -- ./compiler/lua53.can:139 -end -- ./compiler/lua53.can:139 -local r = "" -- ./compiler/lua53.can:141 -if hasPush then -- ./compiler/lua53.can:142 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:143 +end -- ./compiler/lua53.can:129 +return true -- ./compiler/lua53.can:132 +end -- ./compiler/lua53.can:132 +local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:138 +local function push(name, state) -- ./compiler/lua53.can:141 +table["insert"](states[name], state) -- ./compiler/lua53.can:142 +return "" -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:145 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:146 -end -- ./compiler/lua53.can:146 -if t[# t] then -- ./compiler/lua53.can:148 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:149 -end -- ./compiler/lua53.can:149 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:151 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:152 +local function pop(name) -- ./compiler/lua53.can:146 +table["remove"](states[name]) -- ./compiler/lua53.can:147 +return "" -- ./compiler/lua53.can:148 +end -- ./compiler/lua53.can:148 +local function peek(name) -- ./compiler/lua53.can:151 +return states[name][# states[name]] -- ./compiler/lua53.can:152 end -- ./compiler/lua53.can:152 -return r -- ./compiler/lua53.can:154 -end, -- ./compiler/lua53.can:154 -["Do"] = function(t) -- ./compiler/lua53.can:160 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:161 -end, -- ./compiler/lua53.can:161 -["Set"] = function(t) -- ./compiler/lua53.can:164 -if # t == 2 then -- ./compiler/lua53.can:165 -return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:166 -elseif # t == 3 then -- ./compiler/lua53.can:167 -return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:168 -elseif # t == 4 then -- ./compiler/lua53.can:169 -if t[3] == "=" then -- ./compiler/lua53.can:170 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:171 -t[2], -- ./compiler/lua53.can:171 -t[1][1], -- ./compiler/lua53.can:171 -{ -- ./compiler/lua53.can:171 -["tag"] = "Paren", -- ./compiler/lua53.can:171 -t[4][1] -- ./compiler/lua53.can:171 -} -- ./compiler/lua53.can:171 -}, "Op") -- ./compiler/lua53.can:171 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:172 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:173 -t[2], -- ./compiler/lua53.can:173 -t[1][i], -- ./compiler/lua53.can:173 -{ -- ./compiler/lua53.can:173 -["tag"] = "Paren", -- ./compiler/lua53.can:173 -t[4][i] -- ./compiler/lua53.can:173 -} -- ./compiler/lua53.can:173 -}, "Op")) -- ./compiler/lua53.can:173 +local tags -- ./compiler/lua53.can:156 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:158 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:159 +lastInputPos = ast["pos"] -- ./compiler/lua53.can:160 +end -- ./compiler/lua53.can:160 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:162 +end -- ./compiler/lua53.can:162 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:166 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:167 +end -- ./compiler/lua53.can:167 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:169 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:170 +end -- ./compiler/lua53.can:170 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:172 +return "do" .. indent() -- ./compiler/lua53.can:173 end -- ./compiler/lua53.can:173 -return r -- ./compiler/lua53.can:175 -else -- ./compiler/lua53.can:175 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:177 -t[3], -- ./compiler/lua53.can:177 -{ -- ./compiler/lua53.can:177 -["tag"] = "Paren", -- ./compiler/lua53.can:177 -t[4][1] -- ./compiler/lua53.can:177 -}, -- ./compiler/lua53.can:177 -t[1][1] -- ./compiler/lua53.can:177 -}, "Op") -- ./compiler/lua53.can:177 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:178 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:179 -t[3], -- ./compiler/lua53.can:179 -{ -- ./compiler/lua53.can:179 -["tag"] = "Paren", -- ./compiler/lua53.can:179 -t[4][i] -- ./compiler/lua53.can:179 -}, -- ./compiler/lua53.can:179 -t[1][i] -- ./compiler/lua53.can:179 -}, "Op")) -- ./compiler/lua53.can:179 -end -- ./compiler/lua53.can:179 -return r -- ./compiler/lua53.can:181 -end -- ./compiler/lua53.can:181 -else -- ./compiler/lua53.can:181 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:184 -t[2], -- ./compiler/lua53.can:184 -t[1][1], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Op", -- ./compiler/lua53.can:184 -t[4], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Paren", -- ./compiler/lua53.can:184 -t[5][1] -- ./compiler/lua53.can:184 -}, -- ./compiler/lua53.can:184 -t[1][1] -- ./compiler/lua53.can:184 -} -- ./compiler/lua53.can:184 -}, "Op") -- ./compiler/lua53.can:184 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:185 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:186 -t[2], -- ./compiler/lua53.can:186 -t[1][i], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Op", -- ./compiler/lua53.can:186 -t[4], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Paren", -- ./compiler/lua53.can:186 -t[5][i] -- ./compiler/lua53.can:186 -}, -- ./compiler/lua53.can:186 -t[1][i] -- ./compiler/lua53.can:186 -} -- ./compiler/lua53.can:186 -}, "Op")) -- ./compiler/lua53.can:186 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:175 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:176 +end -- ./compiler/lua53.can:176 +tags = setmetatable({ -- ./compiler/lua53.can:180 +["Block"] = function(t) -- ./compiler/lua53.can:182 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:183 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:184 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:185 +hasPush = false -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -return r -- ./compiler/lua53.can:188 -end -- ./compiler/lua53.can:188 -end, -- ./compiler/lua53.can:188 -["While"] = function(t) -- ./compiler/lua53.can:192 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:193 -local r = "while " .. lua(t[1]) .. " do" .. indent() -- ./compiler/lua53.can:194 -if hasContinue then -- ./compiler/lua53.can:195 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:196 +local r = "" -- ./compiler/lua53.can:188 +if hasPush then -- ./compiler/lua53.can:189 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:190 +end -- ./compiler/lua53.can:190 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:192 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:193 +end -- ./compiler/lua53.can:193 +if t[# t] then -- ./compiler/lua53.can:195 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:196 end -- ./compiler/lua53.can:196 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:198 -if hasContinue then -- ./compiler/lua53.can:199 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:200 -end -- ./compiler/lua53.can:200 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:202 -return r -- ./compiler/lua53.can:203 -end, -- ./compiler/lua53.can:203 -["Repeat"] = function(t) -- ./compiler/lua53.can:206 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:207 -local r = "repeat" .. indent() -- ./compiler/lua53.can:208 -if hasContinue then -- ./compiler/lua53.can:209 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:210 -end -- ./compiler/lua53.can:210 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:212 -if hasContinue then -- ./compiler/lua53.can:213 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:216 -return r -- ./compiler/lua53.can:217 -end, -- ./compiler/lua53.can:217 -["If"] = function(t) -- ./compiler/lua53.can:220 -local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() -- ./compiler/lua53.can:221 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:222 -r = r .. ("elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:223 -end -- ./compiler/lua53.can:223 -if # t % 2 == 1 then -- ./compiler/lua53.can:225 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:226 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:198 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:199 +end -- ./compiler/lua53.can:199 +return r -- ./compiler/lua53.can:201 +end, -- ./compiler/lua53.can:201 +["Do"] = function(t) -- ./compiler/lua53.can:207 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:208 +end, -- ./compiler/lua53.can:208 +["Set"] = function(t) -- ./compiler/lua53.can:211 +if # t == 2 then -- ./compiler/lua53.can:212 +return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:213 +elseif # t == 3 then -- ./compiler/lua53.can:214 +return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:215 +elseif # t == 4 then -- ./compiler/lua53.can:216 +if t[3] == "=" then -- ./compiler/lua53.can:217 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:218 +t[2], -- ./compiler/lua53.can:218 +t[1][1], -- ./compiler/lua53.can:218 +{ -- ./compiler/lua53.can:218 +["tag"] = "Paren", -- ./compiler/lua53.can:218 +t[4][1] -- ./compiler/lua53.can:218 +} -- ./compiler/lua53.can:218 +}, "Op") -- ./compiler/lua53.can:218 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:219 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:220 +t[2], -- ./compiler/lua53.can:220 +t[1][i], -- ./compiler/lua53.can:220 +{ -- ./compiler/lua53.can:220 +["tag"] = "Paren", -- ./compiler/lua53.can:220 +t[4][i] -- ./compiler/lua53.can:220 +} -- ./compiler/lua53.can:220 +}, "Op")) -- ./compiler/lua53.can:220 +end -- ./compiler/lua53.can:220 +return r -- ./compiler/lua53.can:222 +else -- ./compiler/lua53.can:222 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:224 +t[3], -- ./compiler/lua53.can:224 +{ -- ./compiler/lua53.can:224 +["tag"] = "Paren", -- ./compiler/lua53.can:224 +t[4][1] -- ./compiler/lua53.can:224 +}, -- ./compiler/lua53.can:224 +t[1][1] -- ./compiler/lua53.can:224 +}, "Op") -- ./compiler/lua53.can:224 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:225 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:226 +t[3], -- ./compiler/lua53.can:226 +{ -- ./compiler/lua53.can:226 +["tag"] = "Paren", -- ./compiler/lua53.can:226 +t[4][i] -- ./compiler/lua53.can:226 +}, -- ./compiler/lua53.can:226 +t[1][i] -- ./compiler/lua53.can:226 +}, "Op")) -- ./compiler/lua53.can:226 end -- ./compiler/lua53.can:226 -return r .. "end" -- ./compiler/lua53.can:228 -end, -- ./compiler/lua53.can:228 -["Fornum"] = function(t) -- ./compiler/lua53.can:231 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:232 -if # t == 5 then -- ./compiler/lua53.can:233 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:234 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:235 -if hasContinue then -- ./compiler/lua53.can:236 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:237 -end -- ./compiler/lua53.can:237 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:239 -if hasContinue then -- ./compiler/lua53.can:240 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:241 -end -- ./compiler/lua53.can:241 -return r .. unindent() .. "end" -- ./compiler/lua53.can:243 -else -- ./compiler/lua53.can:243 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:245 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:246 -if hasContinue then -- ./compiler/lua53.can:247 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:248 -end -- ./compiler/lua53.can:248 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:250 -if hasContinue then -- ./compiler/lua53.can:251 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. unindent() .. "end" -- ./compiler/lua53.can:254 +return r -- ./compiler/lua53.can:228 +end -- ./compiler/lua53.can:228 +else -- ./compiler/lua53.can:228 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:231 +t[2], -- ./compiler/lua53.can:231 +t[1][1], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Op", -- ./compiler/lua53.can:231 +t[4], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Paren", -- ./compiler/lua53.can:231 +t[5][1] -- ./compiler/lua53.can:231 +}, -- ./compiler/lua53.can:231 +t[1][1] -- ./compiler/lua53.can:231 +} -- ./compiler/lua53.can:231 +}, "Op") -- ./compiler/lua53.can:231 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:232 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:233 +t[2], -- ./compiler/lua53.can:233 +t[1][i], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Op", -- ./compiler/lua53.can:233 +t[4], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Paren", -- ./compiler/lua53.can:233 +t[5][i] -- ./compiler/lua53.can:233 +}, -- ./compiler/lua53.can:233 +t[1][i] -- ./compiler/lua53.can:233 +} -- ./compiler/lua53.can:233 +}, "Op")) -- ./compiler/lua53.can:233 +end -- ./compiler/lua53.can:233 +return r -- ./compiler/lua53.can:235 +end -- ./compiler/lua53.can:235 +end, -- ./compiler/lua53.can:235 +["While"] = function(t) -- ./compiler/lua53.can:239 +local r = "" -- ./compiler/lua53.can:240 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:241 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:242 +if # lets > 0 then -- ./compiler/lua53.can:243 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:244 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:245 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:249 +if # lets > 0 then -- ./compiler/lua53.can:250 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:251 +end -- ./compiler/lua53.can:251 +if hasContinue then -- ./compiler/lua53.can:253 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:254 end -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Forin"] = function(t) -- ./compiler/lua53.can:258 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:259 -local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:260 -if hasContinue then -- ./compiler/lua53.can:261 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:262 -end -- ./compiler/lua53.can:262 -r = r .. (lua(t[3])) -- ./compiler/lua53.can:264 -if hasContinue then -- ./compiler/lua53.can:265 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:266 -end -- ./compiler/lua53.can:266 -return r .. unindent() .. "end" -- ./compiler/lua53.can:268 -end, -- ./compiler/lua53.can:268 -["Local"] = function(t) -- ./compiler/lua53.can:271 -local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:272 -if t[2][1] then -- ./compiler/lua53.can:273 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:274 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:256 +if hasContinue then -- ./compiler/lua53.can:257 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:258 +end -- ./compiler/lua53.can:258 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:260 +if # lets > 0 then -- ./compiler/lua53.can:261 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:262 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:263 +end -- ./compiler/lua53.can:263 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:265 +end -- ./compiler/lua53.can:265 +return r -- ./compiler/lua53.can:267 +end, -- ./compiler/lua53.can:267 +["Repeat"] = function(t) -- ./compiler/lua53.can:270 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:271 +local r = "repeat" .. indent() -- ./compiler/lua53.can:272 +if hasContinue then -- ./compiler/lua53.can:273 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:274 end -- ./compiler/lua53.can:274 -return r -- ./compiler/lua53.can:276 -end, -- ./compiler/lua53.can:276 -["Let"] = function(t) -- ./compiler/lua53.can:279 -local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:280 -local r = "local " .. nameList -- ./compiler/lua53.can:281 -if t[2][1] then -- ./compiler/lua53.can:282 -if any(t[2], { -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Function", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Table", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Paren" -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -}) then -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:284 -else -- ./compiler/lua53.can:284 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -return r -- ./compiler/lua53.can:289 -end, -- ./compiler/lua53.can:289 -["Localrec"] = function(t) -- ./compiler/lua53.can:292 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:293 -end, -- ./compiler/lua53.can:293 -["Goto"] = function(t) -- ./compiler/lua53.can:296 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:297 -end, -- ./compiler/lua53.can:297 -["Label"] = function(t) -- ./compiler/lua53.can:300 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:301 -end, -- ./compiler/lua53.can:301 -["Return"] = function(t) -- ./compiler/lua53.can:304 -local push = peek("push") -- ./compiler/lua53.can:305 -if push then -- ./compiler/lua53.can:306 -local r = "" -- ./compiler/lua53.can:307 -for _, val in ipairs(t) do -- ./compiler/lua53.can:308 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:309 -end -- ./compiler/lua53.can:309 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:311 -else -- ./compiler/lua53.can:311 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:313 -end -- ./compiler/lua53.can:313 -end, -- ./compiler/lua53.can:313 -["Push"] = function(t) -- ./compiler/lua53.can:317 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:318 -r = "" -- ./compiler/lua53.can:319 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:320 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:321 -end -- ./compiler/lua53.can:321 -if t[# t] then -- ./compiler/lua53.can:323 -if t[# t]["tag"] == "Call" or t[# t]["tag"] == "Invoke" then -- ./compiler/lua53.can:324 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:325 -else -- ./compiler/lua53.can:325 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -return r -- ./compiler/lua53.can:330 -end, -- ./compiler/lua53.can:330 -["Break"] = function() -- ./compiler/lua53.can:333 -return "break" -- ./compiler/lua53.can:334 -end, -- ./compiler/lua53.can:334 -["Continue"] = function() -- ./compiler/lua53.can:337 -return "goto " .. var("continue") -- ./compiler/lua53.can:338 -end, -- ./compiler/lua53.can:338 -["Nil"] = function() -- ./compiler/lua53.can:345 -return "nil" -- ./compiler/lua53.can:346 -end, -- ./compiler/lua53.can:346 -["Dots"] = function() -- ./compiler/lua53.can:349 -return "..." -- ./compiler/lua53.can:350 -end, -- ./compiler/lua53.can:350 -["Boolean"] = function(t) -- ./compiler/lua53.can:353 -return tostring(t[1]) -- ./compiler/lua53.can:354 -end, -- ./compiler/lua53.can:354 -["Number"] = function(t) -- ./compiler/lua53.can:357 -return tostring(t[1]) -- ./compiler/lua53.can:358 -end, -- ./compiler/lua53.can:358 -["String"] = function(t) -- ./compiler/lua53.can:361 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:362 -end, -- ./compiler/lua53.can:362 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:365 -local r = "(" -- ./compiler/lua53.can:366 -local decl = {} -- ./compiler/lua53.can:367 -if t[1][1] then -- ./compiler/lua53.can:368 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:369 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:370 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:371 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:372 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:373 -r = r .. (id) -- ./compiler/lua53.can:374 -else -- ./compiler/lua53.can:374 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:378 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:379 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:380 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:381 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:382 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:383 -r = r .. (", " .. id) -- ./compiler/lua53.can:384 -else -- ./compiler/lua53.can:384 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:390 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:391 -r = r .. (d .. newline()) -- ./compiler/lua53.can:392 -end -- ./compiler/lua53.can:392 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:394 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:395 -end -- ./compiler/lua53.can:395 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:397 -if hasPush then -- ./compiler/lua53.can:398 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:399 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:276 +if hasContinue then -- ./compiler/lua53.can:277 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:278 +end -- ./compiler/lua53.can:278 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:280 +return r -- ./compiler/lua53.can:281 +end, -- ./compiler/lua53.can:281 +["If"] = function(t) -- ./compiler/lua53.can:284 +local r = "" -- ./compiler/lua53.can:285 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:286 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:287 +if # lets > 0 then -- ./compiler/lua53.can:288 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:289 +toClose = toClose + (1) -- ./compiler/lua53.can:290 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:291 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:295 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:296 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:297 +if # lets > 0 then -- ./compiler/lua53.can:298 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:299 +toClose = toClose + (1) -- ./compiler/lua53.can:300 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:301 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:302 +end -- ./compiler/lua53.can:302 +else -- ./compiler/lua53.can:302 +r = r .. ("else") -- ./compiler/lua53.can:305 +end -- ./compiler/lua53.can:305 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:307 +end -- ./compiler/lua53.can:307 +if # t % 2 == 1 then -- ./compiler/lua53.can:309 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:310 +end -- ./compiler/lua53.can:310 +r = r .. ("end") -- ./compiler/lua53.can:312 +for i = 1, toClose do -- ./compiler/lua53.can:313 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:314 +end -- ./compiler/lua53.can:314 +return r -- ./compiler/lua53.can:316 +end, -- ./compiler/lua53.can:316 +["Fornum"] = function(t) -- ./compiler/lua53.can:319 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:320 +if # t == 5 then -- ./compiler/lua53.can:321 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:322 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:323 +if hasContinue then -- ./compiler/lua53.can:324 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:325 +end -- ./compiler/lua53.can:325 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:327 +if hasContinue then -- ./compiler/lua53.can:328 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:329 +end -- ./compiler/lua53.can:329 +return r .. unindent() .. "end" -- ./compiler/lua53.can:331 +else -- ./compiler/lua53.can:331 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:333 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:334 +if hasContinue then -- ./compiler/lua53.can:335 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:336 +end -- ./compiler/lua53.can:336 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:338 +if hasContinue then -- ./compiler/lua53.can:339 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:340 +end -- ./compiler/lua53.can:340 +return r .. unindent() .. "end" -- ./compiler/lua53.can:342 +end -- ./compiler/lua53.can:342 +end, -- ./compiler/lua53.can:342 +["Forin"] = function(t) -- ./compiler/lua53.can:346 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:347 +local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:348 +if hasContinue then -- ./compiler/lua53.can:349 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:350 +end -- ./compiler/lua53.can:350 +r = r .. (lua(t[3])) -- ./compiler/lua53.can:352 +if hasContinue then -- ./compiler/lua53.can:353 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:354 +end -- ./compiler/lua53.can:354 +return r .. unindent() .. "end" -- ./compiler/lua53.can:356 +end, -- ./compiler/lua53.can:356 +["Local"] = function(t) -- ./compiler/lua53.can:359 +local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:360 +if t[2][1] then -- ./compiler/lua53.can:361 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:362 +end -- ./compiler/lua53.can:362 +return r -- ./compiler/lua53.can:364 +end, -- ./compiler/lua53.can:364 +["Let"] = function(t) -- ./compiler/lua53.can:367 +local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:368 +local r = "local " .. nameList -- ./compiler/lua53.can:369 +if t[2][1] then -- ./compiler/lua53.can:370 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:372 +else -- ./compiler/lua53.can:372 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +return r -- ./compiler/lua53.can:377 +end, -- ./compiler/lua53.can:377 +["Localrec"] = function(t) -- ./compiler/lua53.can:380 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:381 +end, -- ./compiler/lua53.can:381 +["Goto"] = function(t) -- ./compiler/lua53.can:384 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:385 +end, -- ./compiler/lua53.can:385 +["Label"] = function(t) -- ./compiler/lua53.can:388 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:389 +end, -- ./compiler/lua53.can:389 +["Return"] = function(t) -- ./compiler/lua53.can:392 +local push = peek("push") -- ./compiler/lua53.can:393 +if push then -- ./compiler/lua53.can:394 +local r = "" -- ./compiler/lua53.can:395 +for _, val in ipairs(t) do -- ./compiler/lua53.can:396 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:397 +end -- ./compiler/lua53.can:397 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:399 else -- ./compiler/lua53.can:399 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:403 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:404 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -pop("push") -- ./compiler/lua53.can:407 -return r .. unindent() .. "end" -- ./compiler/lua53.can:408 -end, -- ./compiler/lua53.can:408 -["Function"] = function(t) -- ./compiler/lua53.can:410 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:411 -end, -- ./compiler/lua53.can:411 -["Pair"] = function(t) -- ./compiler/lua53.can:414 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:415 -end, -- ./compiler/lua53.can:415 -["Table"] = function(t) -- ./compiler/lua53.can:417 -if # t == 0 then -- ./compiler/lua53.can:418 -return "{}" -- ./compiler/lua53.can:419 -elseif # t == 1 then -- ./compiler/lua53.can:420 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:421 -else -- ./compiler/lua53.can:421 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -end, -- ./compiler/lua53.can:423 -["TableCompr"] = function(t) -- ./compiler/lua53.can:427 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:428 -end, -- ./compiler/lua53.can:428 -["Op"] = function(t) -- ./compiler/lua53.can:431 -local r -- ./compiler/lua53.can:432 -if # t == 2 then -- ./compiler/lua53.can:433 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:434 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:435 -else -- ./compiler/lua53.can:435 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:437 -end -- ./compiler/lua53.can:437 -else -- ./compiler/lua53.can:437 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:440 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:441 -else -- ./compiler/lua53.can:441 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -return r -- ./compiler/lua53.can:446 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:401 +end -- ./compiler/lua53.can:401 +end, -- ./compiler/lua53.can:401 +["Push"] = function(t) -- ./compiler/lua53.can:405 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:406 +r = "" -- ./compiler/lua53.can:407 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:408 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:409 +end -- ./compiler/lua53.can:409 +if t[# t] then -- ./compiler/lua53.can:411 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:412 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:413 +else -- ./compiler/lua53.can:413 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +return r -- ./compiler/lua53.can:418 +end, -- ./compiler/lua53.can:418 +["Break"] = function() -- ./compiler/lua53.can:421 +return "break" -- ./compiler/lua53.can:422 +end, -- ./compiler/lua53.can:422 +["Continue"] = function() -- ./compiler/lua53.can:425 +return "goto " .. var("continue") -- ./compiler/lua53.can:426 +end, -- ./compiler/lua53.can:426 +["Nil"] = function() -- ./compiler/lua53.can:433 +return "nil" -- ./compiler/lua53.can:434 +end, -- ./compiler/lua53.can:434 +["Dots"] = function() -- ./compiler/lua53.can:437 +return "..." -- ./compiler/lua53.can:438 +end, -- ./compiler/lua53.can:438 +["Boolean"] = function(t) -- ./compiler/lua53.can:441 +return tostring(t[1]) -- ./compiler/lua53.can:442 +end, -- ./compiler/lua53.can:442 +["Number"] = function(t) -- ./compiler/lua53.can:445 +return tostring(t[1]) -- ./compiler/lua53.can:446 end, -- ./compiler/lua53.can:446 -["Paren"] = function(t) -- ./compiler/lua53.can:449 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:450 +["String"] = function(t) -- ./compiler/lua53.can:449 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 end, -- ./compiler/lua53.can:450 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:457 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:458 -local r = "(function()" .. indent() -- ./compiler/lua53.can:459 -if hasPush then -- ./compiler/lua53.can:460 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:461 -else -- ./compiler/lua53.can:461 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:465 -if hasPush then -- ./compiler/lua53.can:466 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:467 -end -- ./compiler/lua53.can:467 -pop("push") -- ./compiler/lua53.can:469 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:470 -return r -- ./compiler/lua53.can:471 -end, -- ./compiler/lua53.can:471 -["DoExpr"] = function(t) -- ./compiler/lua53.can:474 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:475 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:476 -end -- ./compiler/lua53.can:476 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:481 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:485 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["IfExpr"] = function(t) -- ./compiler/lua53.can:489 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:490 -local block = t[i] -- ./compiler/lua53.can:491 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:492 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:493 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:453 +local r = "(" -- ./compiler/lua53.can:454 +local decl = {} -- ./compiler/lua53.can:455 +if t[1][1] then -- ./compiler/lua53.can:456 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:457 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:458 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:459 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:460 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:461 +r = r .. (id) -- ./compiler/lua53.can:462 +else -- ./compiler/lua53.can:462 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:464 +end -- ./compiler/lua53.can:464 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:466 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:467 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:468 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:469 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:470 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:471 +r = r .. (", " .. id) -- ./compiler/lua53.can:472 +else -- ./compiler/lua53.can:472 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:478 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:479 +r = r .. (d .. newline()) -- ./compiler/lua53.can:480 +end -- ./compiler/lua53.can:480 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:482 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:483 +end -- ./compiler/lua53.can:483 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:485 +if hasPush then -- ./compiler/lua53.can:486 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:487 +else -- ./compiler/lua53.can:487 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:491 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:492 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:493 end -- ./compiler/lua53.can:493 -end -- ./compiler/lua53.can:493 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:496 +pop("push") -- ./compiler/lua53.can:495 +return r .. unindent() .. "end" -- ./compiler/lua53.can:496 end, -- ./compiler/lua53.can:496 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:499 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:500 -end, -- ./compiler/lua53.can:500 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:503 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:504 -end, -- ./compiler/lua53.can:504 -["Call"] = function(t) -- ./compiler/lua53.can:510 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:511 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:512 -else -- ./compiler/lua53.can:512 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:514 -end -- ./compiler/lua53.can:514 -end, -- ./compiler/lua53.can:514 -["Invoke"] = function(t) -- ./compiler/lua53.can:519 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:520 -return "(" .. lua(t[1]) .. "):" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:521 -else -- ./compiler/lua53.can:521 -return lua(t[1]) .. ":" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:523 -end -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:528 -if start == nil then start = 1 end -- ./compiler/lua53.can:528 -local r -- ./compiler/lua53.can:529 -if t[start] then -- ./compiler/lua53.can:530 -r = lua(t[start]) -- ./compiler/lua53.can:531 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:532 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:533 -end -- ./compiler/lua53.can:533 -else -- ./compiler/lua53.can:533 -r = "" -- ./compiler/lua53.can:536 -end -- ./compiler/lua53.can:536 -return r -- ./compiler/lua53.can:538 +["Function"] = function(t) -- ./compiler/lua53.can:498 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:499 +end, -- ./compiler/lua53.can:499 +["Pair"] = function(t) -- ./compiler/lua53.can:502 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:503 +end, -- ./compiler/lua53.can:503 +["Table"] = function(t) -- ./compiler/lua53.can:505 +if # t == 0 then -- ./compiler/lua53.can:506 +return "{}" -- ./compiler/lua53.can:507 +elseif # t == 1 then -- ./compiler/lua53.can:508 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:509 +else -- ./compiler/lua53.can:509 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:511 +end -- ./compiler/lua53.can:511 +end, -- ./compiler/lua53.can:511 +["TableCompr"] = function(t) -- ./compiler/lua53.can:515 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:516 +end, -- ./compiler/lua53.can:516 +["Op"] = function(t) -- ./compiler/lua53.can:519 +local r -- ./compiler/lua53.can:520 +if # t == 2 then -- ./compiler/lua53.can:521 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:522 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:523 +else -- ./compiler/lua53.can:523 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:525 +end -- ./compiler/lua53.can:525 +else -- ./compiler/lua53.can:525 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:528 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:529 +else -- ./compiler/lua53.can:529 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +return r -- ./compiler/lua53.can:534 +end, -- ./compiler/lua53.can:534 +["Paren"] = function(t) -- ./compiler/lua53.can:537 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:538 end, -- ./compiler/lua53.can:538 -["Id"] = function(t) -- ./compiler/lua53.can:541 -return t[1] -- ./compiler/lua53.can:542 -end, -- ./compiler/lua53.can:542 -["Index"] = function(t) -- ./compiler/lua53.can:545 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:546 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:547 -else -- ./compiler/lua53.can:547 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:549 -end -- ./compiler/lua53.can:549 -end, -- ./compiler/lua53.can:549 -["_opid"] = { -- ./compiler/lua53.can:554 -["add"] = "+", -- ./compiler/lua53.can:555 -["sub"] = "-", -- ./compiler/lua53.can:555 -["mul"] = "*", -- ./compiler/lua53.can:555 -["div"] = "/", -- ./compiler/lua53.can:555 -["idiv"] = "//", -- ./compiler/lua53.can:556 -["mod"] = "%", -- ./compiler/lua53.can:556 -["pow"] = "^", -- ./compiler/lua53.can:556 -["concat"] = "..", -- ./compiler/lua53.can:556 -["band"] = "&", -- ./compiler/lua53.can:557 -["bor"] = "|", -- ./compiler/lua53.can:557 -["bxor"] = "~", -- ./compiler/lua53.can:557 -["shl"] = "<<", -- ./compiler/lua53.can:557 -["shr"] = ">>", -- ./compiler/lua53.can:557 -["eq"] = "==", -- ./compiler/lua53.can:558 -["ne"] = "~=", -- ./compiler/lua53.can:558 -["lt"] = "<", -- ./compiler/lua53.can:558 -["gt"] = ">", -- ./compiler/lua53.can:558 -["le"] = "<=", -- ./compiler/lua53.can:558 -["ge"] = ">=", -- ./compiler/lua53.can:558 -["and"] = "and", -- ./compiler/lua53.can:559 -["or"] = "or", -- ./compiler/lua53.can:559 -["unm"] = "-", -- ./compiler/lua53.can:559 -["len"] = "#", -- ./compiler/lua53.can:559 -["bnot"] = "~", -- ./compiler/lua53.can:559 -["not"] = "not" -- ./compiler/lua53.can:559 -} -- ./compiler/lua53.can:559 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:562 -error("don't know how to compile a " .. tostring(key) .. " to Lua 5.3") -- ./compiler/lua53.can:563 -end }) -- ./compiler/lua53.can:563 -UNPACK = function(list, i, j) -- ./compiler/luajit.can:1 -return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:2 -end -- ./compiler/luajit.can:2 -APPEND = function(t, toAppend) -- ./compiler/luajit.can:4 -return "do" .. indent() .. "local a, p = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #a do" .. indent() .. t .. "[p] = a[i]" .. newline() .. "p = p + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/luajit.can:5 -end -- ./compiler/luajit.can:5 -tags["_opid"]["idiv"] = function(left, right) -- ./compiler/luajit.can:8 -return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/luajit.can:9 -end -- ./compiler/luajit.can:9 -tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:11 -addRequire("bit", "band", "band") -- ./compiler/luajit.can:12 -return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 -end -- ./compiler/luajit.can:13 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:15 -addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:16 -return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 -end -- ./compiler/luajit.can:17 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:19 -addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:20 -return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 -end -- ./compiler/luajit.can:21 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:23 -addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:24 -return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 -end -- ./compiler/luajit.can:25 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:27 -addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:28 -return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:29 -end -- ./compiler/luajit.can:29 -tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:31 -addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:32 -return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:33 -end -- ./compiler/luajit.can:33 -local code = lua(ast) .. newline() -- ./compiler/lua53.can:569 -return requireStr .. code -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -local lua53 = _() or lua53 -- ./compiler/lua53.can:575 -return lua53 -- ./compiler/luajit.can:42 -end -- ./compiler/luajit.can:42 -local luajit = _() or luajit -- ./compiler/luajit.can:46 -package["loaded"]["compiler.luajit"] = luajit or true -- ./compiler/luajit.can:47 -local function _() -- ./compiler/luajit.can:50 +["MethodStub"] = function(t) -- ./compiler/lua53.can:541 +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/lua53.can:547 +end, -- ./compiler/lua53.can:547 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:550 +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/lua53.can:557 +end, -- ./compiler/lua53.can:557 +["LetExpr"] = function(t) -- ./compiler/lua53.can:564 +return lua(t[1][1]) -- ./compiler/lua53.can:565 +end, -- ./compiler/lua53.can:565 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:569 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:570 +local r = "(function()" .. indent() -- ./compiler/lua53.can:571 +if hasPush then -- ./compiler/lua53.can:572 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:573 +else -- ./compiler/lua53.can:573 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:577 +if hasPush then -- ./compiler/lua53.can:578 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:579 +end -- ./compiler/lua53.can:579 +pop("push") -- ./compiler/lua53.can:581 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:582 +return r -- ./compiler/lua53.can:583 +end, -- ./compiler/lua53.can:583 +["DoExpr"] = function(t) -- ./compiler/lua53.can:586 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:587 +t[# t]["tag"] = "Return" -- ./compiler/lua53.can:588 +end -- ./compiler/lua53.can:588 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:590 +end, -- ./compiler/lua53.can:590 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:593 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:594 +end, -- ./compiler/lua53.can:594 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:597 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:598 +end, -- ./compiler/lua53.can:598 +["IfExpr"] = function(t) -- ./compiler/lua53.can:601 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:602 +local block = t[i] -- ./compiler/lua53.can:603 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:604 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:608 +end, -- ./compiler/lua53.can:608 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:611 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:612 +end, -- ./compiler/lua53.can:612 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:615 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:616 +end, -- ./compiler/lua53.can:616 +["Call"] = function(t) -- ./compiler/lua53.can:622 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:623 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:624 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:625 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:626 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:627 +else -- ./compiler/lua53.can:627 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:629 +end -- ./compiler/lua53.can:629 +else -- ./compiler/lua53.can:629 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:632 +end -- ./compiler/lua53.can:632 +end, -- ./compiler/lua53.can:632 +["SafeCall"] = function(t) -- ./compiler/lua53.can:636 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:637 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:638 +else -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:640 +end -- ./compiler/lua53.can:640 +end, -- ./compiler/lua53.can:640 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:645 +if start == nil then start = 1 end -- ./compiler/lua53.can:645 +local r -- ./compiler/lua53.can:646 +if t[start] then -- ./compiler/lua53.can:647 +r = lua(t[start]) -- ./compiler/lua53.can:648 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:649 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:650 +end -- ./compiler/lua53.can:650 +else -- ./compiler/lua53.can:650 +r = "" -- ./compiler/lua53.can:653 +end -- ./compiler/lua53.can:653 +return r -- ./compiler/lua53.can:655 +end, -- ./compiler/lua53.can:655 +["Id"] = function(t) -- ./compiler/lua53.can:658 +return t[1] -- ./compiler/lua53.can:659 +end, -- ./compiler/lua53.can:659 +["Index"] = function(t) -- ./compiler/lua53.can:662 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:663 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:664 +else -- ./compiler/lua53.can:664 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:666 +end -- ./compiler/lua53.can:666 +end, -- ./compiler/lua53.can:666 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:670 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:671 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:672 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:673 +table["insert"](l, 1, t) -- ./compiler/lua53.can:674 +t = t[1] -- ./compiler/lua53.can:675 +end -- ./compiler/lua53.can:675 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:677 +for _, e in ipairs(l) do -- ./compiler/lua53.can:678 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:679 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:680 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:681 +else -- ./compiler/lua53.can:681 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:686 +return r -- ./compiler/lua53.can:687 +else -- ./compiler/lua53.can:687 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:689 +end -- ./compiler/lua53.can:689 +end, -- ./compiler/lua53.can:689 +["_opid"] = { -- ./compiler/lua53.can:694 +["add"] = "+", -- ./compiler/lua53.can:695 +["sub"] = "-", -- ./compiler/lua53.can:695 +["mul"] = "*", -- ./compiler/lua53.can:695 +["div"] = "/", -- ./compiler/lua53.can:695 +["idiv"] = "//", -- ./compiler/lua53.can:696 +["mod"] = "%", -- ./compiler/lua53.can:696 +["pow"] = "^", -- ./compiler/lua53.can:696 +["concat"] = "..", -- ./compiler/lua53.can:696 +["band"] = "&", -- ./compiler/lua53.can:697 +["bor"] = "|", -- ./compiler/lua53.can:697 +["bxor"] = "~", -- ./compiler/lua53.can:697 +["shl"] = "<<", -- ./compiler/lua53.can:697 +["shr"] = ">>", -- ./compiler/lua53.can:697 +["eq"] = "==", -- ./compiler/lua53.can:698 +["ne"] = "~=", -- ./compiler/lua53.can:698 +["lt"] = "<", -- ./compiler/lua53.can:698 +["gt"] = ">", -- ./compiler/lua53.can:698 +["le"] = "<=", -- ./compiler/lua53.can:698 +["ge"] = ">=", -- ./compiler/lua53.can:698 +["and"] = "and", -- ./compiler/lua53.can:699 +["or"] = "or", -- ./compiler/lua53.can:699 +["unm"] = "-", -- ./compiler/lua53.can:699 +["len"] = "#", -- ./compiler/lua53.can:699 +["bnot"] = "~", -- ./compiler/lua53.can:699 +["not"] = "not" -- ./compiler/lua53.can:699 +} -- ./compiler/lua53.can:699 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:702 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:703 +end }) -- ./compiler/lua53.can:703 +targetName = "luajit" -- ./compiler/luajit.can:1 +UNPACK = function(list, i, j) -- ./compiler/luajit.can:3 +return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:4 +end -- ./compiler/luajit.can:4 +APPEND = function(t, toAppend) -- ./compiler/luajit.can:6 +return "do" .. indent() .. "local a, p = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #a do" .. indent() .. t .. "[p] = a[i]" .. newline() .. "p = p + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/luajit.can:7 +end -- ./compiler/luajit.can:7 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/luajit.can:10 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/luajit.can:11 +end -- ./compiler/luajit.can:11 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:13 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:14 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:15 +end -- ./compiler/luajit.can:15 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:17 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:18 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:19 +end -- ./compiler/luajit.can:19 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:21 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:22 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:23 +end -- ./compiler/luajit.can:23 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:25 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:26 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:27 +end -- ./compiler/luajit.can:27 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:29 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:30 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:31 +end -- ./compiler/luajit.can:31 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:33 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:34 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:35 +end -- ./compiler/luajit.can:35 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:709 +return requireStr .. code -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +local lua53 = _() or lua53 -- ./compiler/lua53.can:715 +return lua53 -- ./compiler/luajit.can:44 +end -- ./compiler/luajit.can:44 +local luajit = _() or luajit -- ./compiler/luajit.can:48 +package["loaded"]["compiler.luajit"] = luajit or true -- ./compiler/luajit.can:49 local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 -return function(code, ast, options) -- ./compiler/lua53.can:1 -local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:3 -local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:4 -local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:5 -local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:6 -local indentLevel = 0 -- ./compiler/lua53.can:9 -local function newline() -- ./compiler/lua53.can:11 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:12 -if options["mapLines"] then -- ./compiler/lua53.can:13 -local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:14 +local function _() -- ./compiler/luajit.can:56 +local targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +return function(code, ast, options) -- ./compiler/lua53.can:3 +local lastInputPos = 1 -- last token position in the input code -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- last token position in the previous line of code in the input code -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- last found code source name (from the original file) -- ./compiler/lua53.can:7 +local lastLine = 1 -- last found line number (from the original file) -- ./compiler/lua53.can:8 +local indentLevel = 0 -- ./compiler/lua53.can:11 +local function newline() -- ./compiler/lua53.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua53.can:14 +if options["mapLines"] then -- ./compiler/lua53.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua53.can:16 local source, line = sub:sub(1, sub:find("\ ")):match("%-%- (.-)%:(%d+)\ -") -- ./compiler/lua53.can:15 -if source and line then -- ./compiler/lua53.can:17 -lastSource = source -- ./compiler/lua53.can:18 -lastLine = tonumber(line) -- ./compiler/lua53.can:19 -else -- ./compiler/lua53.can:19 +") -- ./compiler/lua53.can:17 +if source and line then -- ./compiler/lua53.can:19 +lastSource = source -- ./compiler/lua53.can:20 +lastLine = tonumber(line) -- ./compiler/lua53.can:21 +else -- ./compiler/lua53.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua53.can:21 -lastLine = lastLine + (1) -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -end -- ./compiler/lua53.can:22 -prevLinePos = lastInputPos -- ./compiler/lua53.can:26 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:28 -end -- ./compiler/lua53.can:28 -return r -- ./compiler/lua53.can:30 +") do -- ./compiler/lua53.can:23 +lastLine = lastLine + (1) -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +end -- ./compiler/lua53.can:24 +prevLinePos = lastInputPos -- ./compiler/lua53.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua53.can:30 end -- ./compiler/lua53.can:30 -local function indent() -- ./compiler/lua53.can:33 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:34 -return newline() -- ./compiler/lua53.can:35 -end -- ./compiler/lua53.can:35 -local function unindent() -- ./compiler/lua53.can:38 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:39 -return newline() -- ./compiler/lua53.can:40 -end -- ./compiler/lua53.can:40 -local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:44 -local requireStr = "" -- ./compiler/lua53.can:45 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:47 -if not required[mod] then -- ./compiler/lua53.can:48 -requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:49 -required[mod] = true -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -end -- ./compiler/lua53.can:50 -local function var(name) -- ./compiler/lua53.can:56 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:57 -end -- ./compiler/lua53.can:57 -local loop = { -- loops tags -- ./compiler/lua53.can:61 -"While", -- loops tags -- ./compiler/lua53.can:61 -"Repeat", -- loops tags -- ./compiler/lua53.can:61 -"Fornum", -- loops tags -- ./compiler/lua53.can:61 -"Forin" -- loops tags -- ./compiler/lua53.can:61 -} -- loops tags -- ./compiler/lua53.can:61 -local func = { -- function scope tags -- ./compiler/lua53.can:62 -"Function", -- function scope tags -- ./compiler/lua53.can:62 -"TableCompr", -- function scope tags -- ./compiler/lua53.can:62 -"DoExpr", -- function scope tags -- ./compiler/lua53.can:62 -"WhileExpr", -- function scope tags -- ./compiler/lua53.can:62 -"RepeatExpr", -- function scope tags -- ./compiler/lua53.can:62 -"IfExpr", -- function scope tags -- ./compiler/lua53.can:62 -"FornumExpr", -- function scope tags -- ./compiler/lua53.can:62 -"ForinExpr" -- function scope tags -- ./compiler/lua53.can:62 -} -- function scope tags -- ./compiler/lua53.can:62 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:65 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:65 -local tagsCheck = {} -- ./compiler/lua53.can:66 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:67 -tagsCheck[tag] = true -- ./compiler/lua53.can:68 -end -- ./compiler/lua53.can:68 -local nofollowCheck = {} -- ./compiler/lua53.can:70 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:71 -nofollowCheck[tag] = true -- ./compiler/lua53.can:72 -end -- ./compiler/lua53.can:72 -for _, node in ipairs(list) do -- ./compiler/lua53.can:74 -if type(node) == "table" then -- ./compiler/lua53.can:75 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:76 -return node -- ./compiler/lua53.can:77 -end -- ./compiler/lua53.can:77 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:79 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:80 -if r then -- ./compiler/lua53.can:81 -return r -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -end -- ./compiler/lua53.can:81 -return nil -- ./compiler/lua53.can:85 -end -- ./compiler/lua53.can:85 -local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:91 -local function push(name, state) -- ./compiler/lua53.can:94 -table["insert"](states[name], state) -- ./compiler/lua53.can:95 -return "" -- ./compiler/lua53.can:96 +return r -- ./compiler/lua53.can:32 +end -- ./compiler/lua53.can:32 +local function indent() -- ./compiler/lua53.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:36 +return newline() -- ./compiler/lua53.can:37 +end -- ./compiler/lua53.can:37 +local function unindent() -- ./compiler/lua53.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 +return newline() -- ./compiler/lua53.can:42 +end -- ./compiler/lua53.can:42 +local required = {} -- { ["module"] = true, ... } -- ./compiler/lua53.can:46 +local requireStr = "" -- ./compiler/lua53.can:47 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:49 +if not required[mod] then -- ./compiler/lua53.can:50 +requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]) -- ./compiler/lua53.can:51 +required[mod] = true -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +end -- ./compiler/lua53.can:52 +local function var(name) -- ./compiler/lua53.can:58 +return options["variablePrefix"] .. name -- ./compiler/lua53.can:59 +end -- ./compiler/lua53.can:59 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:63 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:64 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:68 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:68 +local tagsCheck = {} -- ./compiler/lua53.can:69 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:70 +tagsCheck[tag] = true -- ./compiler/lua53.can:71 +end -- ./compiler/lua53.can:71 +local nofollowCheck = {} -- ./compiler/lua53.can:73 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:74 +nofollowCheck[tag] = true -- ./compiler/lua53.can:75 +end -- ./compiler/lua53.can:75 +for _, node in ipairs(list) do -- ./compiler/lua53.can:77 +if type(node) == "table" then -- ./compiler/lua53.can:78 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:79 +return node -- ./compiler/lua53.can:80 +end -- ./compiler/lua53.can:80 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:82 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:83 +if r then -- ./compiler/lua53.can:84 +return r -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +end -- ./compiler/lua53.can:84 +return nil -- ./compiler/lua53.can:88 +end -- ./compiler/lua53.can:88 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:93 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:93 +local tagsCheck = {} -- ./compiler/lua53.can:94 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:95 +tagsCheck[tag] = true -- ./compiler/lua53.can:96 end -- ./compiler/lua53.can:96 -local function pop(name) -- ./compiler/lua53.can:99 -table["remove"](states[name]) -- ./compiler/lua53.can:100 -return "" -- ./compiler/lua53.can:101 -end -- ./compiler/lua53.can:101 -local function peek(name) -- ./compiler/lua53.can:104 -return states[name][# states[name]] -- ./compiler/lua53.can:105 -end -- ./compiler/lua53.can:105 -local tags -- ./compiler/lua53.can:109 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:111 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:112 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:113 -end -- ./compiler/lua53.can:113 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:115 +local nofollowCheck = {} -- ./compiler/lua53.can:98 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:99 +nofollowCheck[tag] = true -- ./compiler/lua53.can:100 +end -- ./compiler/lua53.can:100 +local found = {} -- ./compiler/lua53.can:102 +for _, node in ipairs(list) do -- ./compiler/lua53.can:103 +if type(node) == "table" then -- ./compiler/lua53.can:104 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:105 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:106 +table["insert"](found, n) -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +end -- ./compiler/lua53.can:107 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:110 +table["insert"](found, node) -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +end -- ./compiler/lua53.can:111 +return found -- ./compiler/lua53.can:115 end -- ./compiler/lua53.can:115 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:119 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:122 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:123 -end -- ./compiler/lua53.can:123 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:125 -return "do" .. indent() -- ./compiler/lua53.can:126 -end -- ./compiler/lua53.can:126 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:128 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +local function all(list, tags) -- ./compiler/lua53.can:119 +for _, node in ipairs(list) do -- ./compiler/lua53.can:120 +local ok = false -- ./compiler/lua53.can:121 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:122 +if node["tag"] == tag then -- ./compiler/lua53.can:123 +ok = true -- ./compiler/lua53.can:124 +break -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +end -- ./compiler/lua53.can:125 +if not ok then -- ./compiler/lua53.can:128 +return false -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 -tags = setmetatable({ -- ./compiler/lua53.can:133 -["Block"] = function(t) -- ./compiler/lua53.can:135 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:136 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:137 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:138 -hasPush = false -- ./compiler/lua53.can:139 -end -- ./compiler/lua53.can:139 -local r = "" -- ./compiler/lua53.can:141 -if hasPush then -- ./compiler/lua53.can:142 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:143 +end -- ./compiler/lua53.can:129 +return true -- ./compiler/lua53.can:132 +end -- ./compiler/lua53.can:132 +local states = { ["push"] = {} } -- push stack variable names -- ./compiler/lua53.can:138 +local function push(name, state) -- ./compiler/lua53.can:141 +table["insert"](states[name], state) -- ./compiler/lua53.can:142 +return "" -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:145 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:146 -end -- ./compiler/lua53.can:146 -if t[# t] then -- ./compiler/lua53.can:148 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:149 -end -- ./compiler/lua53.can:149 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:151 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:152 +local function pop(name) -- ./compiler/lua53.can:146 +table["remove"](states[name]) -- ./compiler/lua53.can:147 +return "" -- ./compiler/lua53.can:148 +end -- ./compiler/lua53.can:148 +local function peek(name) -- ./compiler/lua53.can:151 +return states[name][# states[name]] -- ./compiler/lua53.can:152 end -- ./compiler/lua53.can:152 -return r -- ./compiler/lua53.can:154 -end, -- ./compiler/lua53.can:154 -["Do"] = function(t) -- ./compiler/lua53.can:160 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:161 -end, -- ./compiler/lua53.can:161 -["Set"] = function(t) -- ./compiler/lua53.can:164 -if # t == 2 then -- ./compiler/lua53.can:165 -return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:166 -elseif # t == 3 then -- ./compiler/lua53.can:167 -return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:168 -elseif # t == 4 then -- ./compiler/lua53.can:169 -if t[3] == "=" then -- ./compiler/lua53.can:170 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:171 -t[2], -- ./compiler/lua53.can:171 -t[1][1], -- ./compiler/lua53.can:171 -{ -- ./compiler/lua53.can:171 -["tag"] = "Paren", -- ./compiler/lua53.can:171 -t[4][1] -- ./compiler/lua53.can:171 -} -- ./compiler/lua53.can:171 -}, "Op") -- ./compiler/lua53.can:171 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:172 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:173 -t[2], -- ./compiler/lua53.can:173 -t[1][i], -- ./compiler/lua53.can:173 -{ -- ./compiler/lua53.can:173 -["tag"] = "Paren", -- ./compiler/lua53.can:173 -t[4][i] -- ./compiler/lua53.can:173 -} -- ./compiler/lua53.can:173 -}, "Op")) -- ./compiler/lua53.can:173 +local tags -- ./compiler/lua53.can:156 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:158 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:159 +lastInputPos = ast["pos"] -- ./compiler/lua53.can:160 +end -- ./compiler/lua53.can:160 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:162 +end -- ./compiler/lua53.can:162 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:166 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:167 +end -- ./compiler/lua53.can:167 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:169 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:170 +end -- ./compiler/lua53.can:170 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:172 +return "do" .. indent() -- ./compiler/lua53.can:173 end -- ./compiler/lua53.can:173 -return r -- ./compiler/lua53.can:175 -else -- ./compiler/lua53.can:175 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:177 -t[3], -- ./compiler/lua53.can:177 -{ -- ./compiler/lua53.can:177 -["tag"] = "Paren", -- ./compiler/lua53.can:177 -t[4][1] -- ./compiler/lua53.can:177 -}, -- ./compiler/lua53.can:177 -t[1][1] -- ./compiler/lua53.can:177 -}, "Op") -- ./compiler/lua53.can:177 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:178 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:179 -t[3], -- ./compiler/lua53.can:179 -{ -- ./compiler/lua53.can:179 -["tag"] = "Paren", -- ./compiler/lua53.can:179 -t[4][i] -- ./compiler/lua53.can:179 -}, -- ./compiler/lua53.can:179 -t[1][i] -- ./compiler/lua53.can:179 -}, "Op")) -- ./compiler/lua53.can:179 -end -- ./compiler/lua53.can:179 -return r -- ./compiler/lua53.can:181 -end -- ./compiler/lua53.can:181 -else -- ./compiler/lua53.can:181 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:184 -t[2], -- ./compiler/lua53.can:184 -t[1][1], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Op", -- ./compiler/lua53.can:184 -t[4], -- ./compiler/lua53.can:184 -{ -- ./compiler/lua53.can:184 -["tag"] = "Paren", -- ./compiler/lua53.can:184 -t[5][1] -- ./compiler/lua53.can:184 -}, -- ./compiler/lua53.can:184 -t[1][1] -- ./compiler/lua53.can:184 -} -- ./compiler/lua53.can:184 -}, "Op") -- ./compiler/lua53.can:184 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:185 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:186 -t[2], -- ./compiler/lua53.can:186 -t[1][i], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Op", -- ./compiler/lua53.can:186 -t[4], -- ./compiler/lua53.can:186 -{ -- ./compiler/lua53.can:186 -["tag"] = "Paren", -- ./compiler/lua53.can:186 -t[5][i] -- ./compiler/lua53.can:186 -}, -- ./compiler/lua53.can:186 -t[1][i] -- ./compiler/lua53.can:186 -} -- ./compiler/lua53.can:186 -}, "Op")) -- ./compiler/lua53.can:186 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:175 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:176 +end -- ./compiler/lua53.can:176 +tags = setmetatable({ -- ./compiler/lua53.can:180 +["Block"] = function(t) -- ./compiler/lua53.can:182 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:183 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:184 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:185 +hasPush = false -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -return r -- ./compiler/lua53.can:188 -end -- ./compiler/lua53.can:188 -end, -- ./compiler/lua53.can:188 -["While"] = function(t) -- ./compiler/lua53.can:192 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:193 -local r = "while " .. lua(t[1]) .. " do" .. indent() -- ./compiler/lua53.can:194 -if hasContinue then -- ./compiler/lua53.can:195 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:196 +local r = "" -- ./compiler/lua53.can:188 +if hasPush then -- ./compiler/lua53.can:189 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:190 +end -- ./compiler/lua53.can:190 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:192 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:193 +end -- ./compiler/lua53.can:193 +if t[# t] then -- ./compiler/lua53.can:195 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:196 end -- ./compiler/lua53.can:196 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:198 -if hasContinue then -- ./compiler/lua53.can:199 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:200 -end -- ./compiler/lua53.can:200 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:202 -return r -- ./compiler/lua53.can:203 -end, -- ./compiler/lua53.can:203 -["Repeat"] = function(t) -- ./compiler/lua53.can:206 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:207 -local r = "repeat" .. indent() -- ./compiler/lua53.can:208 -if hasContinue then -- ./compiler/lua53.can:209 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:210 -end -- ./compiler/lua53.can:210 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:212 -if hasContinue then -- ./compiler/lua53.can:213 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:216 -return r -- ./compiler/lua53.can:217 -end, -- ./compiler/lua53.can:217 -["If"] = function(t) -- ./compiler/lua53.can:220 -local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() -- ./compiler/lua53.can:221 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:222 -r = r .. ("elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:223 -end -- ./compiler/lua53.can:223 -if # t % 2 == 1 then -- ./compiler/lua53.can:225 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:226 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:198 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:199 +end -- ./compiler/lua53.can:199 +return r -- ./compiler/lua53.can:201 +end, -- ./compiler/lua53.can:201 +["Do"] = function(t) -- ./compiler/lua53.can:207 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:208 +end, -- ./compiler/lua53.can:208 +["Set"] = function(t) -- ./compiler/lua53.can:211 +if # t == 2 then -- ./compiler/lua53.can:212 +return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:213 +elseif # t == 3 then -- ./compiler/lua53.can:214 +return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:215 +elseif # t == 4 then -- ./compiler/lua53.can:216 +if t[3] == "=" then -- ./compiler/lua53.can:217 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:218 +t[2], -- ./compiler/lua53.can:218 +t[1][1], -- ./compiler/lua53.can:218 +{ -- ./compiler/lua53.can:218 +["tag"] = "Paren", -- ./compiler/lua53.can:218 +t[4][1] -- ./compiler/lua53.can:218 +} -- ./compiler/lua53.can:218 +}, "Op") -- ./compiler/lua53.can:218 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:219 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:220 +t[2], -- ./compiler/lua53.can:220 +t[1][i], -- ./compiler/lua53.can:220 +{ -- ./compiler/lua53.can:220 +["tag"] = "Paren", -- ./compiler/lua53.can:220 +t[4][i] -- ./compiler/lua53.can:220 +} -- ./compiler/lua53.can:220 +}, "Op")) -- ./compiler/lua53.can:220 +end -- ./compiler/lua53.can:220 +return r -- ./compiler/lua53.can:222 +else -- ./compiler/lua53.can:222 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:224 +t[3], -- ./compiler/lua53.can:224 +{ -- ./compiler/lua53.can:224 +["tag"] = "Paren", -- ./compiler/lua53.can:224 +t[4][1] -- ./compiler/lua53.can:224 +}, -- ./compiler/lua53.can:224 +t[1][1] -- ./compiler/lua53.can:224 +}, "Op") -- ./compiler/lua53.can:224 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:225 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:226 +t[3], -- ./compiler/lua53.can:226 +{ -- ./compiler/lua53.can:226 +["tag"] = "Paren", -- ./compiler/lua53.can:226 +t[4][i] -- ./compiler/lua53.can:226 +}, -- ./compiler/lua53.can:226 +t[1][i] -- ./compiler/lua53.can:226 +}, "Op")) -- ./compiler/lua53.can:226 end -- ./compiler/lua53.can:226 -return r .. "end" -- ./compiler/lua53.can:228 -end, -- ./compiler/lua53.can:228 -["Fornum"] = function(t) -- ./compiler/lua53.can:231 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:232 -if # t == 5 then -- ./compiler/lua53.can:233 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:234 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:235 -if hasContinue then -- ./compiler/lua53.can:236 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:237 -end -- ./compiler/lua53.can:237 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:239 -if hasContinue then -- ./compiler/lua53.can:240 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:241 -end -- ./compiler/lua53.can:241 -return r .. unindent() .. "end" -- ./compiler/lua53.can:243 -else -- ./compiler/lua53.can:243 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:245 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:246 -if hasContinue then -- ./compiler/lua53.can:247 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:248 -end -- ./compiler/lua53.can:248 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:250 -if hasContinue then -- ./compiler/lua53.can:251 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. unindent() .. "end" -- ./compiler/lua53.can:254 +return r -- ./compiler/lua53.can:228 +end -- ./compiler/lua53.can:228 +else -- ./compiler/lua53.can:228 +local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:231 +t[2], -- ./compiler/lua53.can:231 +t[1][1], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Op", -- ./compiler/lua53.can:231 +t[4], -- ./compiler/lua53.can:231 +{ -- ./compiler/lua53.can:231 +["tag"] = "Paren", -- ./compiler/lua53.can:231 +t[5][1] -- ./compiler/lua53.can:231 +}, -- ./compiler/lua53.can:231 +t[1][1] -- ./compiler/lua53.can:231 +} -- ./compiler/lua53.can:231 +}, "Op") -- ./compiler/lua53.can:231 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:232 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:233 +t[2], -- ./compiler/lua53.can:233 +t[1][i], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Op", -- ./compiler/lua53.can:233 +t[4], -- ./compiler/lua53.can:233 +{ -- ./compiler/lua53.can:233 +["tag"] = "Paren", -- ./compiler/lua53.can:233 +t[5][i] -- ./compiler/lua53.can:233 +}, -- ./compiler/lua53.can:233 +t[1][i] -- ./compiler/lua53.can:233 +} -- ./compiler/lua53.can:233 +}, "Op")) -- ./compiler/lua53.can:233 +end -- ./compiler/lua53.can:233 +return r -- ./compiler/lua53.can:235 +end -- ./compiler/lua53.can:235 +end, -- ./compiler/lua53.can:235 +["While"] = function(t) -- ./compiler/lua53.can:239 +local r = "" -- ./compiler/lua53.can:240 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:241 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:242 +if # lets > 0 then -- ./compiler/lua53.can:243 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:244 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:245 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +end -- ./compiler/lua53.can:246 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:249 +if # lets > 0 then -- ./compiler/lua53.can:250 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:251 +end -- ./compiler/lua53.can:251 +if hasContinue then -- ./compiler/lua53.can:253 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:254 end -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Forin"] = function(t) -- ./compiler/lua53.can:258 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:259 -local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:260 -if hasContinue then -- ./compiler/lua53.can:261 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:262 -end -- ./compiler/lua53.can:262 -r = r .. (lua(t[3])) -- ./compiler/lua53.can:264 -if hasContinue then -- ./compiler/lua53.can:265 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:266 -end -- ./compiler/lua53.can:266 -return r .. unindent() .. "end" -- ./compiler/lua53.can:268 -end, -- ./compiler/lua53.can:268 -["Local"] = function(t) -- ./compiler/lua53.can:271 -local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:272 -if t[2][1] then -- ./compiler/lua53.can:273 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:274 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:256 +if hasContinue then -- ./compiler/lua53.can:257 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:258 +end -- ./compiler/lua53.can:258 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:260 +if # lets > 0 then -- ./compiler/lua53.can:261 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:262 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:263 +end -- ./compiler/lua53.can:263 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:265 +end -- ./compiler/lua53.can:265 +return r -- ./compiler/lua53.can:267 +end, -- ./compiler/lua53.can:267 +["Repeat"] = function(t) -- ./compiler/lua53.can:270 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:271 +local r = "repeat" .. indent() -- ./compiler/lua53.can:272 +if hasContinue then -- ./compiler/lua53.can:273 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:274 end -- ./compiler/lua53.can:274 -return r -- ./compiler/lua53.can:276 -end, -- ./compiler/lua53.can:276 -["Let"] = function(t) -- ./compiler/lua53.can:279 -local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:280 -local r = "local " .. nameList -- ./compiler/lua53.can:281 -if t[2][1] then -- ./compiler/lua53.can:282 -if any(t[2], { -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Function", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Table", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -"Paren" -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -}) then -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:283 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:284 -else -- ./compiler/lua53.can:284 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -end -- ./compiler/lua53.can:286 -return r -- ./compiler/lua53.can:289 -end, -- ./compiler/lua53.can:289 -["Localrec"] = function(t) -- ./compiler/lua53.can:292 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:293 -end, -- ./compiler/lua53.can:293 -["Goto"] = function(t) -- ./compiler/lua53.can:296 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:297 -end, -- ./compiler/lua53.can:297 -["Label"] = function(t) -- ./compiler/lua53.can:300 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:301 -end, -- ./compiler/lua53.can:301 -["Return"] = function(t) -- ./compiler/lua53.can:304 -local push = peek("push") -- ./compiler/lua53.can:305 -if push then -- ./compiler/lua53.can:306 -local r = "" -- ./compiler/lua53.can:307 -for _, val in ipairs(t) do -- ./compiler/lua53.can:308 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:309 -end -- ./compiler/lua53.can:309 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:311 -else -- ./compiler/lua53.can:311 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:313 -end -- ./compiler/lua53.can:313 -end, -- ./compiler/lua53.can:313 -["Push"] = function(t) -- ./compiler/lua53.can:317 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:318 -r = "" -- ./compiler/lua53.can:319 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:320 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:321 -end -- ./compiler/lua53.can:321 -if t[# t] then -- ./compiler/lua53.can:323 -if t[# t]["tag"] == "Call" or t[# t]["tag"] == "Invoke" then -- ./compiler/lua53.can:324 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:325 -else -- ./compiler/lua53.can:325 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -end -- ./compiler/lua53.can:327 -return r -- ./compiler/lua53.can:330 -end, -- ./compiler/lua53.can:330 -["Break"] = function() -- ./compiler/lua53.can:333 -return "break" -- ./compiler/lua53.can:334 -end, -- ./compiler/lua53.can:334 -["Continue"] = function() -- ./compiler/lua53.can:337 -return "goto " .. var("continue") -- ./compiler/lua53.can:338 -end, -- ./compiler/lua53.can:338 -["Nil"] = function() -- ./compiler/lua53.can:345 -return "nil" -- ./compiler/lua53.can:346 -end, -- ./compiler/lua53.can:346 -["Dots"] = function() -- ./compiler/lua53.can:349 -return "..." -- ./compiler/lua53.can:350 -end, -- ./compiler/lua53.can:350 -["Boolean"] = function(t) -- ./compiler/lua53.can:353 -return tostring(t[1]) -- ./compiler/lua53.can:354 -end, -- ./compiler/lua53.can:354 -["Number"] = function(t) -- ./compiler/lua53.can:357 -return tostring(t[1]) -- ./compiler/lua53.can:358 -end, -- ./compiler/lua53.can:358 -["String"] = function(t) -- ./compiler/lua53.can:361 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:362 -end, -- ./compiler/lua53.can:362 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:365 -local r = "(" -- ./compiler/lua53.can:366 -local decl = {} -- ./compiler/lua53.can:367 -if t[1][1] then -- ./compiler/lua53.can:368 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:369 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:370 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:371 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:372 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:373 -r = r .. (id) -- ./compiler/lua53.can:374 -else -- ./compiler/lua53.can:374 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:378 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:379 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:380 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:381 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:382 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:383 -r = r .. (", " .. id) -- ./compiler/lua53.can:384 -else -- ./compiler/lua53.can:384 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -end -- ./compiler/lua53.can:386 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:390 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:391 -r = r .. (d .. newline()) -- ./compiler/lua53.can:392 -end -- ./compiler/lua53.can:392 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:394 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:395 -end -- ./compiler/lua53.can:395 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:397 -if hasPush then -- ./compiler/lua53.can:398 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:399 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:276 +if hasContinue then -- ./compiler/lua53.can:277 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:278 +end -- ./compiler/lua53.can:278 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:280 +return r -- ./compiler/lua53.can:281 +end, -- ./compiler/lua53.can:281 +["If"] = function(t) -- ./compiler/lua53.can:284 +local r = "" -- ./compiler/lua53.can:285 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:286 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:287 +if # lets > 0 then -- ./compiler/lua53.can:288 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:289 +toClose = toClose + (1) -- ./compiler/lua53.can:290 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:291 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +end -- ./compiler/lua53.can:292 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:295 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:296 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:297 +if # lets > 0 then -- ./compiler/lua53.can:298 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:299 +toClose = toClose + (1) -- ./compiler/lua53.can:300 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:301 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:302 +end -- ./compiler/lua53.can:302 +else -- ./compiler/lua53.can:302 +r = r .. ("else") -- ./compiler/lua53.can:305 +end -- ./compiler/lua53.can:305 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:307 +end -- ./compiler/lua53.can:307 +if # t % 2 == 1 then -- ./compiler/lua53.can:309 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:310 +end -- ./compiler/lua53.can:310 +r = r .. ("end") -- ./compiler/lua53.can:312 +for i = 1, toClose do -- ./compiler/lua53.can:313 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:314 +end -- ./compiler/lua53.can:314 +return r -- ./compiler/lua53.can:316 +end, -- ./compiler/lua53.can:316 +["Fornum"] = function(t) -- ./compiler/lua53.can:319 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:320 +if # t == 5 then -- ./compiler/lua53.can:321 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:322 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:323 +if hasContinue then -- ./compiler/lua53.can:324 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:325 +end -- ./compiler/lua53.can:325 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:327 +if hasContinue then -- ./compiler/lua53.can:328 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:329 +end -- ./compiler/lua53.can:329 +return r .. unindent() .. "end" -- ./compiler/lua53.can:331 +else -- ./compiler/lua53.can:331 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:333 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:334 +if hasContinue then -- ./compiler/lua53.can:335 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:336 +end -- ./compiler/lua53.can:336 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:338 +if hasContinue then -- ./compiler/lua53.can:339 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:340 +end -- ./compiler/lua53.can:340 +return r .. unindent() .. "end" -- ./compiler/lua53.can:342 +end -- ./compiler/lua53.can:342 +end, -- ./compiler/lua53.can:342 +["Forin"] = function(t) -- ./compiler/lua53.can:346 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:347 +local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:348 +if hasContinue then -- ./compiler/lua53.can:349 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:350 +end -- ./compiler/lua53.can:350 +r = r .. (lua(t[3])) -- ./compiler/lua53.can:352 +if hasContinue then -- ./compiler/lua53.can:353 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:354 +end -- ./compiler/lua53.can:354 +return r .. unindent() .. "end" -- ./compiler/lua53.can:356 +end, -- ./compiler/lua53.can:356 +["Local"] = function(t) -- ./compiler/lua53.can:359 +local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:360 +if t[2][1] then -- ./compiler/lua53.can:361 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:362 +end -- ./compiler/lua53.can:362 +return r -- ./compiler/lua53.can:364 +end, -- ./compiler/lua53.can:364 +["Let"] = function(t) -- ./compiler/lua53.can:367 +local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:368 +local r = "local " .. nameList -- ./compiler/lua53.can:369 +if t[2][1] then -- ./compiler/lua53.can:370 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:371 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:372 +else -- ./compiler/lua53.can:372 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +end -- ./compiler/lua53.can:374 +return r -- ./compiler/lua53.can:377 +end, -- ./compiler/lua53.can:377 +["Localrec"] = function(t) -- ./compiler/lua53.can:380 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:381 +end, -- ./compiler/lua53.can:381 +["Goto"] = function(t) -- ./compiler/lua53.can:384 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:385 +end, -- ./compiler/lua53.can:385 +["Label"] = function(t) -- ./compiler/lua53.can:388 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:389 +end, -- ./compiler/lua53.can:389 +["Return"] = function(t) -- ./compiler/lua53.can:392 +local push = peek("push") -- ./compiler/lua53.can:393 +if push then -- ./compiler/lua53.can:394 +local r = "" -- ./compiler/lua53.can:395 +for _, val in ipairs(t) do -- ./compiler/lua53.can:396 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:397 +end -- ./compiler/lua53.can:397 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:399 else -- ./compiler/lua53.can:399 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:401 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:403 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:404 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -pop("push") -- ./compiler/lua53.can:407 -return r .. unindent() .. "end" -- ./compiler/lua53.can:408 -end, -- ./compiler/lua53.can:408 -["Function"] = function(t) -- ./compiler/lua53.can:410 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:411 -end, -- ./compiler/lua53.can:411 -["Pair"] = function(t) -- ./compiler/lua53.can:414 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:415 -end, -- ./compiler/lua53.can:415 -["Table"] = function(t) -- ./compiler/lua53.can:417 -if # t == 0 then -- ./compiler/lua53.can:418 -return "{}" -- ./compiler/lua53.can:419 -elseif # t == 1 then -- ./compiler/lua53.can:420 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:421 -else -- ./compiler/lua53.can:421 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -end, -- ./compiler/lua53.can:423 -["TableCompr"] = function(t) -- ./compiler/lua53.can:427 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:428 -end, -- ./compiler/lua53.can:428 -["Op"] = function(t) -- ./compiler/lua53.can:431 -local r -- ./compiler/lua53.can:432 -if # t == 2 then -- ./compiler/lua53.can:433 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:434 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:435 -else -- ./compiler/lua53.can:435 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:437 -end -- ./compiler/lua53.can:437 -else -- ./compiler/lua53.can:437 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:440 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:441 -else -- ./compiler/lua53.can:441 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -end -- ./compiler/lua53.can:443 -return r -- ./compiler/lua53.can:446 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:401 +end -- ./compiler/lua53.can:401 +end, -- ./compiler/lua53.can:401 +["Push"] = function(t) -- ./compiler/lua53.can:405 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:406 +r = "" -- ./compiler/lua53.can:407 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:408 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:409 +end -- ./compiler/lua53.can:409 +if t[# t] then -- ./compiler/lua53.can:411 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:412 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:413 +else -- ./compiler/lua53.can:413 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +end -- ./compiler/lua53.can:415 +return r -- ./compiler/lua53.can:418 +end, -- ./compiler/lua53.can:418 +["Break"] = function() -- ./compiler/lua53.can:421 +return "break" -- ./compiler/lua53.can:422 +end, -- ./compiler/lua53.can:422 +["Continue"] = function() -- ./compiler/lua53.can:425 +return "goto " .. var("continue") -- ./compiler/lua53.can:426 +end, -- ./compiler/lua53.can:426 +["Nil"] = function() -- ./compiler/lua53.can:433 +return "nil" -- ./compiler/lua53.can:434 +end, -- ./compiler/lua53.can:434 +["Dots"] = function() -- ./compiler/lua53.can:437 +return "..." -- ./compiler/lua53.can:438 +end, -- ./compiler/lua53.can:438 +["Boolean"] = function(t) -- ./compiler/lua53.can:441 +return tostring(t[1]) -- ./compiler/lua53.can:442 +end, -- ./compiler/lua53.can:442 +["Number"] = function(t) -- ./compiler/lua53.can:445 +return tostring(t[1]) -- ./compiler/lua53.can:446 end, -- ./compiler/lua53.can:446 -["Paren"] = function(t) -- ./compiler/lua53.can:449 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:450 +["String"] = function(t) -- ./compiler/lua53.can:449 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 end, -- ./compiler/lua53.can:450 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:457 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:458 -local r = "(function()" .. indent() -- ./compiler/lua53.can:459 -if hasPush then -- ./compiler/lua53.can:460 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:461 -else -- ./compiler/lua53.can:461 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:463 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:465 -if hasPush then -- ./compiler/lua53.can:466 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:467 -end -- ./compiler/lua53.can:467 -pop("push") -- ./compiler/lua53.can:469 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:470 -return r -- ./compiler/lua53.can:471 -end, -- ./compiler/lua53.can:471 -["DoExpr"] = function(t) -- ./compiler/lua53.can:474 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:475 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:476 -end -- ./compiler/lua53.can:476 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:481 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:485 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["IfExpr"] = function(t) -- ./compiler/lua53.can:489 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:490 -local block = t[i] -- ./compiler/lua53.can:491 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:492 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:493 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:453 +local r = "(" -- ./compiler/lua53.can:454 +local decl = {} -- ./compiler/lua53.can:455 +if t[1][1] then -- ./compiler/lua53.can:456 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:457 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:458 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:459 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:460 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:461 +r = r .. (id) -- ./compiler/lua53.can:462 +else -- ./compiler/lua53.can:462 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:464 +end -- ./compiler/lua53.can:464 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:466 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:467 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:468 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:469 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:470 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:471 +r = r .. (", " .. id) -- ./compiler/lua53.can:472 +else -- ./compiler/lua53.can:472 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +end -- ./compiler/lua53.can:474 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:478 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:479 +r = r .. (d .. newline()) -- ./compiler/lua53.can:480 +end -- ./compiler/lua53.can:480 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:482 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:483 +end -- ./compiler/lua53.can:483 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:485 +if hasPush then -- ./compiler/lua53.can:486 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:487 +else -- ./compiler/lua53.can:487 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:489 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:491 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:492 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:493 end -- ./compiler/lua53.can:493 -end -- ./compiler/lua53.can:493 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:496 +pop("push") -- ./compiler/lua53.can:495 +return r .. unindent() .. "end" -- ./compiler/lua53.can:496 end, -- ./compiler/lua53.can:496 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:499 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:500 -end, -- ./compiler/lua53.can:500 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:503 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:504 -end, -- ./compiler/lua53.can:504 -["Call"] = function(t) -- ./compiler/lua53.can:510 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:511 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:512 -else -- ./compiler/lua53.can:512 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:514 -end -- ./compiler/lua53.can:514 -end, -- ./compiler/lua53.can:514 -["Invoke"] = function(t) -- ./compiler/lua53.can:519 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:520 -return "(" .. lua(t[1]) .. "):" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:521 -else -- ./compiler/lua53.can:521 -return lua(t[1]) .. ":" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:523 -end -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:528 -if start == nil then start = 1 end -- ./compiler/lua53.can:528 -local r -- ./compiler/lua53.can:529 -if t[start] then -- ./compiler/lua53.can:530 -r = lua(t[start]) -- ./compiler/lua53.can:531 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:532 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:533 -end -- ./compiler/lua53.can:533 -else -- ./compiler/lua53.can:533 -r = "" -- ./compiler/lua53.can:536 -end -- ./compiler/lua53.can:536 -return r -- ./compiler/lua53.can:538 +["Function"] = function(t) -- ./compiler/lua53.can:498 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:499 +end, -- ./compiler/lua53.can:499 +["Pair"] = function(t) -- ./compiler/lua53.can:502 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:503 +end, -- ./compiler/lua53.can:503 +["Table"] = function(t) -- ./compiler/lua53.can:505 +if # t == 0 then -- ./compiler/lua53.can:506 +return "{}" -- ./compiler/lua53.can:507 +elseif # t == 1 then -- ./compiler/lua53.can:508 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:509 +else -- ./compiler/lua53.can:509 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:511 +end -- ./compiler/lua53.can:511 +end, -- ./compiler/lua53.can:511 +["TableCompr"] = function(t) -- ./compiler/lua53.can:515 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:516 +end, -- ./compiler/lua53.can:516 +["Op"] = function(t) -- ./compiler/lua53.can:519 +local r -- ./compiler/lua53.can:520 +if # t == 2 then -- ./compiler/lua53.can:521 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:522 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:523 +else -- ./compiler/lua53.can:523 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:525 +end -- ./compiler/lua53.can:525 +else -- ./compiler/lua53.can:525 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:528 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:529 +else -- ./compiler/lua53.can:529 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +end -- ./compiler/lua53.can:531 +return r -- ./compiler/lua53.can:534 +end, -- ./compiler/lua53.can:534 +["Paren"] = function(t) -- ./compiler/lua53.can:537 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:538 end, -- ./compiler/lua53.can:538 -["Id"] = function(t) -- ./compiler/lua53.can:541 -return t[1] -- ./compiler/lua53.can:542 -end, -- ./compiler/lua53.can:542 -["Index"] = function(t) -- ./compiler/lua53.can:545 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:546 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:547 -else -- ./compiler/lua53.can:547 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:549 -end -- ./compiler/lua53.can:549 -end, -- ./compiler/lua53.can:549 -["_opid"] = { -- ./compiler/lua53.can:554 -["add"] = "+", -- ./compiler/lua53.can:555 -["sub"] = "-", -- ./compiler/lua53.can:555 -["mul"] = "*", -- ./compiler/lua53.can:555 -["div"] = "/", -- ./compiler/lua53.can:555 -["idiv"] = "//", -- ./compiler/lua53.can:556 -["mod"] = "%", -- ./compiler/lua53.can:556 -["pow"] = "^", -- ./compiler/lua53.can:556 -["concat"] = "..", -- ./compiler/lua53.can:556 -["band"] = "&", -- ./compiler/lua53.can:557 -["bor"] = "|", -- ./compiler/lua53.can:557 -["bxor"] = "~", -- ./compiler/lua53.can:557 -["shl"] = "<<", -- ./compiler/lua53.can:557 -["shr"] = ">>", -- ./compiler/lua53.can:557 -["eq"] = "==", -- ./compiler/lua53.can:558 -["ne"] = "~=", -- ./compiler/lua53.can:558 -["lt"] = "<", -- ./compiler/lua53.can:558 -["gt"] = ">", -- ./compiler/lua53.can:558 -["le"] = "<=", -- ./compiler/lua53.can:558 -["ge"] = ">=", -- ./compiler/lua53.can:558 -["and"] = "and", -- ./compiler/lua53.can:559 -["or"] = "or", -- ./compiler/lua53.can:559 -["unm"] = "-", -- ./compiler/lua53.can:559 -["len"] = "#", -- ./compiler/lua53.can:559 -["bnot"] = "~", -- ./compiler/lua53.can:559 -["not"] = "not" -- ./compiler/lua53.can:559 -} -- ./compiler/lua53.can:559 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:562 -error("don't know how to compile a " .. tostring(key) .. " to Lua 5.3") -- ./compiler/lua53.can:563 -end }) -- ./compiler/lua53.can:563 -UNPACK = function(list, i, j) -- ./compiler/luajit.can:1 -return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:2 -end -- ./compiler/luajit.can:2 -APPEND = function(t, toAppend) -- ./compiler/luajit.can:4 -return "do" .. indent() .. "local a, p = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #a do" .. indent() .. t .. "[p] = a[i]" .. newline() .. "p = p + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/luajit.can:5 -end -- ./compiler/luajit.can:5 -tags["_opid"]["idiv"] = function(left, right) -- ./compiler/luajit.can:8 -return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/luajit.can:9 -end -- ./compiler/luajit.can:9 -tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:11 -addRequire("bit", "band", "band") -- ./compiler/luajit.can:12 -return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 -end -- ./compiler/luajit.can:13 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:15 -addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:16 -return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 -end -- ./compiler/luajit.can:17 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:19 -addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:20 -return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 -end -- ./compiler/luajit.can:21 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:23 -addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:24 -return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 -end -- ./compiler/luajit.can:25 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:27 -addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:28 -return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:29 -end -- ./compiler/luajit.can:29 -tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:31 -addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:32 -return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:33 -end -- ./compiler/luajit.can:33 -states["continue"] = {} -- when in a loop that use continue -- ./compiler/lua51.can:1 -CONTINUE_START = function() -- ./compiler/lua51.can:3 -return "local " .. var("break") .. newline() .. "repeat" .. indent() .. push("continue", var("break")) -- ./compiler/lua51.can:4 -end -- ./compiler/lua51.can:4 -CONTINUE_STOP = function() -- ./compiler/lua51.can:6 -return pop("continue") .. unindent() .. "until true" .. newline() .. "if " .. var("break") .. " then break end" -- ./compiler/lua51.can:7 -end -- ./compiler/lua51.can:7 -tags["Continue"] = function() -- ./compiler/lua51.can:10 -return "break" -- ./compiler/lua51.can:11 -end -- ./compiler/lua51.can:11 -tags["Break"] = function() -- ./compiler/lua51.can:13 -local inContinue = peek("continue") -- ./compiler/lua51.can:14 -if inContinue then -- ./compiler/lua51.can:15 -return inContinue .. " = true" .. newline() .. "break" -- ./compiler/lua51.can:16 -else -- ./compiler/lua51.can:16 -return "break" -- ./compiler/lua51.can:18 -end -- ./compiler/lua51.can:18 -end -- ./compiler/lua51.can:18 -tags["Goto"] = function() -- ./compiler/lua51.can:22 -error("Lua 5.1 does not support the goto keyword") -- ./compiler/lua51.can:23 -end -- ./compiler/lua51.can:23 -tags["Label"] = function() -- ./compiler/lua51.can:25 -error("Lua 5.1 does not support labels") -- ./compiler/lua51.can:26 -end -- ./compiler/lua51.can:26 -local code = lua(ast) .. newline() -- ./compiler/lua53.can:569 -return requireStr .. code -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -end -- ./compiler/lua53.can:570 -local lua53 = _() or lua53 -- ./compiler/lua53.can:575 -return lua53 -- ./compiler/luajit.can:42 -end -- ./compiler/luajit.can:42 -local luajit = _() or luajit -- ./compiler/luajit.can:46 -return luajit -- ./compiler/lua51.can:33 -end -- ./compiler/lua51.can:33 -local lua51 = _() or lua51 -- ./compiler/lua51.can:37 -package["loaded"]["compiler.lua51"] = lua51 or true -- ./compiler/lua51.can:38 -local function _() -- ./compiler/lua51.can:42 +["MethodStub"] = function(t) -- ./compiler/lua53.can:541 +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/lua53.can:547 +end, -- ./compiler/lua53.can:547 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:550 +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/lua53.can:557 +end, -- ./compiler/lua53.can:557 +["LetExpr"] = function(t) -- ./compiler/lua53.can:564 +return lua(t[1][1]) -- ./compiler/lua53.can:565 +end, -- ./compiler/lua53.can:565 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:569 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:570 +local r = "(function()" .. indent() -- ./compiler/lua53.can:571 +if hasPush then -- ./compiler/lua53.can:572 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:573 +else -- ./compiler/lua53.can:573 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:575 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:577 +if hasPush then -- ./compiler/lua53.can:578 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:579 +end -- ./compiler/lua53.can:579 +pop("push") -- ./compiler/lua53.can:581 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:582 +return r -- ./compiler/lua53.can:583 +end, -- ./compiler/lua53.can:583 +["DoExpr"] = function(t) -- ./compiler/lua53.can:586 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:587 +t[# t]["tag"] = "Return" -- ./compiler/lua53.can:588 +end -- ./compiler/lua53.can:588 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:590 +end, -- ./compiler/lua53.can:590 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:593 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:594 +end, -- ./compiler/lua53.can:594 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:597 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:598 +end, -- ./compiler/lua53.can:598 +["IfExpr"] = function(t) -- ./compiler/lua53.can:601 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:602 +local block = t[i] -- ./compiler/lua53.can:603 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:604 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +end -- ./compiler/lua53.can:605 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:608 +end, -- ./compiler/lua53.can:608 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:611 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:612 +end, -- ./compiler/lua53.can:612 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:615 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:616 +end, -- ./compiler/lua53.can:616 +["Call"] = function(t) -- ./compiler/lua53.can:622 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:623 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:624 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:625 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:626 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:627 +else -- ./compiler/lua53.can:627 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:629 +end -- ./compiler/lua53.can:629 +else -- ./compiler/lua53.can:629 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:632 +end -- ./compiler/lua53.can:632 +end, -- ./compiler/lua53.can:632 +["SafeCall"] = function(t) -- ./compiler/lua53.can:636 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:637 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:638 +else -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:640 +end -- ./compiler/lua53.can:640 +end, -- ./compiler/lua53.can:640 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:645 +if start == nil then start = 1 end -- ./compiler/lua53.can:645 +local r -- ./compiler/lua53.can:646 +if t[start] then -- ./compiler/lua53.can:647 +r = lua(t[start]) -- ./compiler/lua53.can:648 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:649 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:650 +end -- ./compiler/lua53.can:650 +else -- ./compiler/lua53.can:650 +r = "" -- ./compiler/lua53.can:653 +end -- ./compiler/lua53.can:653 +return r -- ./compiler/lua53.can:655 +end, -- ./compiler/lua53.can:655 +["Id"] = function(t) -- ./compiler/lua53.can:658 +return t[1] -- ./compiler/lua53.can:659 +end, -- ./compiler/lua53.can:659 +["Index"] = function(t) -- ./compiler/lua53.can:662 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:663 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:664 +else -- ./compiler/lua53.can:664 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:666 +end -- ./compiler/lua53.can:666 +end, -- ./compiler/lua53.can:666 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:670 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:671 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:672 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:673 +table["insert"](l, 1, t) -- ./compiler/lua53.can:674 +t = t[1] -- ./compiler/lua53.can:675 +end -- ./compiler/lua53.can:675 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:677 +for _, e in ipairs(l) do -- ./compiler/lua53.can:678 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:679 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:680 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:681 +else -- ./compiler/lua53.can:681 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +end -- ./compiler/lua53.can:683 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:686 +return r -- ./compiler/lua53.can:687 +else -- ./compiler/lua53.can:687 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:689 +end -- ./compiler/lua53.can:689 +end, -- ./compiler/lua53.can:689 +["_opid"] = { -- ./compiler/lua53.can:694 +["add"] = "+", -- ./compiler/lua53.can:695 +["sub"] = "-", -- ./compiler/lua53.can:695 +["mul"] = "*", -- ./compiler/lua53.can:695 +["div"] = "/", -- ./compiler/lua53.can:695 +["idiv"] = "//", -- ./compiler/lua53.can:696 +["mod"] = "%", -- ./compiler/lua53.can:696 +["pow"] = "^", -- ./compiler/lua53.can:696 +["concat"] = "..", -- ./compiler/lua53.can:696 +["band"] = "&", -- ./compiler/lua53.can:697 +["bor"] = "|", -- ./compiler/lua53.can:697 +["bxor"] = "~", -- ./compiler/lua53.can:697 +["shl"] = "<<", -- ./compiler/lua53.can:697 +["shr"] = ">>", -- ./compiler/lua53.can:697 +["eq"] = "==", -- ./compiler/lua53.can:698 +["ne"] = "~=", -- ./compiler/lua53.can:698 +["lt"] = "<", -- ./compiler/lua53.can:698 +["gt"] = ">", -- ./compiler/lua53.can:698 +["le"] = "<=", -- ./compiler/lua53.can:698 +["ge"] = ">=", -- ./compiler/lua53.can:698 +["and"] = "and", -- ./compiler/lua53.can:699 +["or"] = "or", -- ./compiler/lua53.can:699 +["unm"] = "-", -- ./compiler/lua53.can:699 +["len"] = "#", -- ./compiler/lua53.can:699 +["bnot"] = "~", -- ./compiler/lua53.can:699 +["not"] = "not" -- ./compiler/lua53.can:699 +} -- ./compiler/lua53.can:699 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:702 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:703 +end }) -- ./compiler/lua53.can:703 +targetName = "luajit" -- ./compiler/luajit.can:1 +UNPACK = function(list, i, j) -- ./compiler/luajit.can:3 +return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:4 +end -- ./compiler/luajit.can:4 +APPEND = function(t, toAppend) -- ./compiler/luajit.can:6 +return "do" .. indent() .. "local a, p = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #a do" .. indent() .. t .. "[p] = a[i]" .. newline() .. "p = p + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/luajit.can:7 +end -- ./compiler/luajit.can:7 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/luajit.can:10 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/luajit.can:11 +end -- ./compiler/luajit.can:11 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:13 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:14 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:15 +end -- ./compiler/luajit.can:15 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:17 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:18 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:19 +end -- ./compiler/luajit.can:19 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:21 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:22 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:23 +end -- ./compiler/luajit.can:23 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:25 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:26 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:27 +end -- ./compiler/luajit.can:27 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:29 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:30 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:31 +end -- ./compiler/luajit.can:31 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:33 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:34 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:35 +end -- ./compiler/luajit.can:35 +targetName = "Lua 5.1" -- ./compiler/lua51.can:1 +states["continue"] = {} -- when in a loop that use continue -- ./compiler/lua51.can:3 +CONTINUE_START = function() -- ./compiler/lua51.can:5 +return "local " .. var("break") .. newline() .. "repeat" .. indent() .. push("continue", var("break")) -- ./compiler/lua51.can:6 +end -- ./compiler/lua51.can:6 +CONTINUE_STOP = function() -- ./compiler/lua51.can:8 +return pop("continue") .. unindent() .. "until true" .. newline() .. "if " .. var("break") .. " then break end" -- ./compiler/lua51.can:9 +end -- ./compiler/lua51.can:9 +tags["Continue"] = function() -- ./compiler/lua51.can:12 +return "break" -- ./compiler/lua51.can:13 +end -- ./compiler/lua51.can:13 +tags["Break"] = function() -- ./compiler/lua51.can:15 +local inContinue = peek("continue") -- ./compiler/lua51.can:16 +if inContinue then -- ./compiler/lua51.can:17 +return inContinue .. " = true" .. newline() .. "break" -- ./compiler/lua51.can:18 +else -- ./compiler/lua51.can:18 +return "break" -- ./compiler/lua51.can:20 +end -- ./compiler/lua51.can:20 +end -- ./compiler/lua51.can:20 +tags["Goto"] = nil -- ./compiler/lua51.can:25 +tags["Label"] = nil -- ./compiler/lua51.can:26 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:709 +return requireStr .. code -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +end -- ./compiler/lua53.can:710 +local lua53 = _() or lua53 -- ./compiler/lua53.can:715 +return lua53 -- ./compiler/luajit.can:44 +end -- ./compiler/luajit.can:44 +local luajit = _() or luajit -- ./compiler/luajit.can:48 +return luajit -- ./compiler/lua51.can:32 +end -- ./compiler/lua51.can:32 +local lua51 = _() or lua51 -- ./compiler/lua51.can:36 +package["loaded"]["compiler.lua51"] = lua51 or true -- ./compiler/lua51.can:37 +local function _() -- ./compiler/lua51.can:41 local scope = {} -- ./lib/lua-parser/scope.lua:4 scope["lineno"] = function(s, i) -- ./lib/lua-parser/scope.lua:6 if i == 1 then -- ./lib/lua-parser/scope.lua:7 @@ -2198,333 +2569,342 @@ end -- ./lib/lua-parser/validator.lua:156 end -- ./lib/lua-parser/validator.lua:156 return true -- ./lib/lua-parser/validator.lua:158 end -- ./lib/lua-parser/validator.lua:158 -local function traverse_invoke(env, invoke) -- ./lib/lua-parser/validator.lua:161 -local status, msg = traverse_exp(env, invoke[1]) -- ./lib/lua-parser/validator.lua:162 +local function traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:161 +local status, msg = traverse_varlist(env, stm[1]) -- ./lib/lua-parser/validator.lua:162 if not status then -- ./lib/lua-parser/validator.lua:163 return status, msg -- ./lib/lua-parser/validator.lua:163 end -- ./lib/lua-parser/validator.lua:163 -for i = 3, # invoke do -- ./lib/lua-parser/validator.lua:164 -status, msg = traverse_exp(env, invoke[i]) -- ./lib/lua-parser/validator.lua:165 -if not status then -- ./lib/lua-parser/validator.lua:166 -return status, msg -- ./lib/lua-parser/validator.lua:166 +status, msg = traverse_explist(env, stm[# stm]) -- ./lib/lua-parser/validator.lua:164 +if not status then -- ./lib/lua-parser/validator.lua:165 +return status, msg -- ./lib/lua-parser/validator.lua:165 +end -- ./lib/lua-parser/validator.lua:165 +return true -- ./lib/lua-parser/validator.lua:166 end -- ./lib/lua-parser/validator.lua:166 -end -- ./lib/lua-parser/validator.lua:166 -return true -- ./lib/lua-parser/validator.lua:168 -end -- ./lib/lua-parser/validator.lua:168 -local function traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:171 -local status, msg = traverse_varlist(env, stm[1]) -- ./lib/lua-parser/validator.lua:172 -if not status then -- ./lib/lua-parser/validator.lua:173 -return status, msg -- ./lib/lua-parser/validator.lua:173 -end -- ./lib/lua-parser/validator.lua:173 -status, msg = traverse_explist(env, stm[# stm]) -- ./lib/lua-parser/validator.lua:174 -if not status then -- ./lib/lua-parser/validator.lua:175 -return status, msg -- ./lib/lua-parser/validator.lua:175 -end -- ./lib/lua-parser/validator.lua:175 -return true -- ./lib/lua-parser/validator.lua:176 -end -- ./lib/lua-parser/validator.lua:176 -local function traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:179 -if not insideloop(env) then -- ./lib/lua-parser/validator.lua:180 -local msg = " not inside a loop" -- ./lib/lua-parser/validator.lua:181 -return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./lib/lua-parser/validator.lua:182 +local function traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:169 +if not insideloop(env) then -- ./lib/lua-parser/validator.lua:170 +local msg = " not inside a loop" -- ./lib/lua-parser/validator.lua:171 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./lib/lua-parser/validator.lua:172 +end -- ./lib/lua-parser/validator.lua:172 +return true -- ./lib/lua-parser/validator.lua:174 +end -- ./lib/lua-parser/validator.lua:174 +local function traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:177 +if not insideloop(env) then -- ./lib/lua-parser/validator.lua:178 +local msg = " not inside a loop" -- ./lib/lua-parser/validator.lua:179 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./lib/lua-parser/validator.lua:180 +end -- ./lib/lua-parser/validator.lua:180 +return true -- ./lib/lua-parser/validator.lua:182 end -- ./lib/lua-parser/validator.lua:182 -return true -- ./lib/lua-parser/validator.lua:184 -end -- ./lib/lua-parser/validator.lua:184 -local function traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:187 -if not insideloop(env) then -- ./lib/lua-parser/validator.lua:188 -local msg = " not inside a loop" -- ./lib/lua-parser/validator.lua:189 -return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./lib/lua-parser/validator.lua:190 -end -- ./lib/lua-parser/validator.lua:190 -return true -- ./lib/lua-parser/validator.lua:192 -end -- ./lib/lua-parser/validator.lua:192 -local function traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:195 -local status, msg = traverse_explist(env, stm) -- ./lib/lua-parser/validator.lua:196 +local function traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:185 +local status, msg = traverse_explist(env, stm) -- ./lib/lua-parser/validator.lua:186 +if not status then -- ./lib/lua-parser/validator.lua:187 +return status, msg -- ./lib/lua-parser/validator.lua:187 +end -- ./lib/lua-parser/validator.lua:187 +return true -- ./lib/lua-parser/validator.lua:188 +end -- ./lib/lua-parser/validator.lua:188 +local function traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:191 +begin_loop(env) -- ./lib/lua-parser/validator.lua:192 +new_scope(env) -- ./lib/lua-parser/validator.lua:193 +local status, msg = traverse_explist(env, stm[2]) -- ./lib/lua-parser/validator.lua:194 +if not status then -- ./lib/lua-parser/validator.lua:195 +return status, msg -- ./lib/lua-parser/validator.lua:195 +end -- ./lib/lua-parser/validator.lua:195 +status, msg = traverse_block(env, stm[3]) -- ./lib/lua-parser/validator.lua:196 if not status then -- ./lib/lua-parser/validator.lua:197 return status, msg -- ./lib/lua-parser/validator.lua:197 end -- ./lib/lua-parser/validator.lua:197 -return true -- ./lib/lua-parser/validator.lua:198 -end -- ./lib/lua-parser/validator.lua:198 -local function traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:201 -begin_loop(env) -- ./lib/lua-parser/validator.lua:202 -new_scope(env) -- ./lib/lua-parser/validator.lua:203 -local status, msg = traverse_explist(env, stm[2]) -- ./lib/lua-parser/validator.lua:204 -if not status then -- ./lib/lua-parser/validator.lua:205 -return status, msg -- ./lib/lua-parser/validator.lua:205 -end -- ./lib/lua-parser/validator.lua:205 -status, msg = traverse_block(env, stm[3]) -- ./lib/lua-parser/validator.lua:206 -if not status then -- ./lib/lua-parser/validator.lua:207 -return status, msg -- ./lib/lua-parser/validator.lua:207 -end -- ./lib/lua-parser/validator.lua:207 -end_scope(env) -- ./lib/lua-parser/validator.lua:208 -end_loop(env) -- ./lib/lua-parser/validator.lua:209 -return true -- ./lib/lua-parser/validator.lua:210 +end_scope(env) -- ./lib/lua-parser/validator.lua:198 +end_loop(env) -- ./lib/lua-parser/validator.lua:199 +return true -- ./lib/lua-parser/validator.lua:200 +end -- ./lib/lua-parser/validator.lua:200 +local function traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:203 +local status, msg -- ./lib/lua-parser/validator.lua:204 +begin_loop(env) -- ./lib/lua-parser/validator.lua:205 +new_scope(env) -- ./lib/lua-parser/validator.lua:206 +status, msg = traverse_exp(env, stm[2]) -- ./lib/lua-parser/validator.lua:207 +if not status then -- ./lib/lua-parser/validator.lua:208 +return status, msg -- ./lib/lua-parser/validator.lua:208 +end -- ./lib/lua-parser/validator.lua:208 +status, msg = traverse_exp(env, stm[3]) -- ./lib/lua-parser/validator.lua:209 +if not status then -- ./lib/lua-parser/validator.lua:210 +return status, msg -- ./lib/lua-parser/validator.lua:210 end -- ./lib/lua-parser/validator.lua:210 -local function traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:213 -local status, msg -- ./lib/lua-parser/validator.lua:214 -begin_loop(env) -- ./lib/lua-parser/validator.lua:215 -new_scope(env) -- ./lib/lua-parser/validator.lua:216 -status, msg = traverse_exp(env, stm[2]) -- ./lib/lua-parser/validator.lua:217 +if stm[5] then -- ./lib/lua-parser/validator.lua:211 +status, msg = traverse_exp(env, stm[4]) -- ./lib/lua-parser/validator.lua:212 +if not status then -- ./lib/lua-parser/validator.lua:213 +return status, msg -- ./lib/lua-parser/validator.lua:213 +end -- ./lib/lua-parser/validator.lua:213 +status, msg = traverse_block(env, stm[5]) -- ./lib/lua-parser/validator.lua:214 +if not status then -- ./lib/lua-parser/validator.lua:215 +return status, msg -- ./lib/lua-parser/validator.lua:215 +end -- ./lib/lua-parser/validator.lua:215 +else -- ./lib/lua-parser/validator.lua:215 +status, msg = traverse_block(env, stm[4]) -- ./lib/lua-parser/validator.lua:217 if not status then -- ./lib/lua-parser/validator.lua:218 return status, msg -- ./lib/lua-parser/validator.lua:218 end -- ./lib/lua-parser/validator.lua:218 -status, msg = traverse_exp(env, stm[3]) -- ./lib/lua-parser/validator.lua:219 -if not status then -- ./lib/lua-parser/validator.lua:220 -return status, msg -- ./lib/lua-parser/validator.lua:220 -end -- ./lib/lua-parser/validator.lua:220 -if stm[5] then -- ./lib/lua-parser/validator.lua:221 -status, msg = traverse_exp(env, stm[4]) -- ./lib/lua-parser/validator.lua:222 -if not status then -- ./lib/lua-parser/validator.lua:223 -return status, msg -- ./lib/lua-parser/validator.lua:223 -end -- ./lib/lua-parser/validator.lua:223 -status, msg = traverse_block(env, stm[5]) -- ./lib/lua-parser/validator.lua:224 -if not status then -- ./lib/lua-parser/validator.lua:225 -return status, msg -- ./lib/lua-parser/validator.lua:225 -end -- ./lib/lua-parser/validator.lua:225 -else -- ./lib/lua-parser/validator.lua:225 -status, msg = traverse_block(env, stm[4]) -- ./lib/lua-parser/validator.lua:227 -if not status then -- ./lib/lua-parser/validator.lua:228 -return status, msg -- ./lib/lua-parser/validator.lua:228 +end -- ./lib/lua-parser/validator.lua:218 +end_scope(env) -- ./lib/lua-parser/validator.lua:220 +end_loop(env) -- ./lib/lua-parser/validator.lua:221 +return true -- ./lib/lua-parser/validator.lua:222 +end -- ./lib/lua-parser/validator.lua:222 +local function traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:225 +local status, msg = set_pending_goto(env, stm) -- ./lib/lua-parser/validator.lua:226 +if not status then -- ./lib/lua-parser/validator.lua:227 +return status, msg -- ./lib/lua-parser/validator.lua:227 +end -- ./lib/lua-parser/validator.lua:227 +return true -- ./lib/lua-parser/validator.lua:228 end -- ./lib/lua-parser/validator.lua:228 -end -- ./lib/lua-parser/validator.lua:228 -end_scope(env) -- ./lib/lua-parser/validator.lua:230 -end_loop(env) -- ./lib/lua-parser/validator.lua:231 -return true -- ./lib/lua-parser/validator.lua:232 -end -- ./lib/lua-parser/validator.lua:232 -local function traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:235 -local status, msg = set_pending_goto(env, stm) -- ./lib/lua-parser/validator.lua:236 -if not status then -- ./lib/lua-parser/validator.lua:237 -return status, msg -- ./lib/lua-parser/validator.lua:237 -end -- ./lib/lua-parser/validator.lua:237 -return true -- ./lib/lua-parser/validator.lua:238 -end -- ./lib/lua-parser/validator.lua:238 -local function traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:241 -local len = # stm -- ./lib/lua-parser/validator.lua:242 -if len % 2 == 0 then -- ./lib/lua-parser/validator.lua:243 -for i = 1, len, 2 do -- ./lib/lua-parser/validator.lua:244 -local status, msg = traverse_exp(env, stm[i]) -- ./lib/lua-parser/validator.lua:245 -if not status then -- ./lib/lua-parser/validator.lua:246 -return status, msg -- ./lib/lua-parser/validator.lua:246 -end -- ./lib/lua-parser/validator.lua:246 -status, msg = traverse_block(env, stm[i + 1]) -- ./lib/lua-parser/validator.lua:247 +local function traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:231 +local status, msg = traverse_explist(env, stm[2]) -- ./lib/lua-parser/validator.lua:232 +if not status then -- ./lib/lua-parser/validator.lua:233 +return status, msg -- ./lib/lua-parser/validator.lua:233 +end -- ./lib/lua-parser/validator.lua:233 +return true -- ./lib/lua-parser/validator.lua:234 +end -- ./lib/lua-parser/validator.lua:234 +local function traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:237 +local status, msg = traverse_exp(env, stm[2][1]) -- ./lib/lua-parser/validator.lua:238 +if not status then -- ./lib/lua-parser/validator.lua:239 +return status, msg -- ./lib/lua-parser/validator.lua:239 +end -- ./lib/lua-parser/validator.lua:239 +return true -- ./lib/lua-parser/validator.lua:240 +end -- ./lib/lua-parser/validator.lua:240 +local function traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:243 +local len = # stm -- ./lib/lua-parser/validator.lua:244 +if len % 2 == 0 then -- ./lib/lua-parser/validator.lua:245 +for i = 1, len, 2 do -- ./lib/lua-parser/validator.lua:246 +local status, msg = traverse_exp(env, stm[i]) -- ./lib/lua-parser/validator.lua:247 if not status then -- ./lib/lua-parser/validator.lua:248 return status, msg -- ./lib/lua-parser/validator.lua:248 end -- ./lib/lua-parser/validator.lua:248 -end -- ./lib/lua-parser/validator.lua:248 -else -- ./lib/lua-parser/validator.lua:248 -for i = 1, len - 1, 2 do -- ./lib/lua-parser/validator.lua:251 -local status, msg = traverse_exp(env, stm[i]) -- ./lib/lua-parser/validator.lua:252 -if not status then -- ./lib/lua-parser/validator.lua:253 -return status, msg -- ./lib/lua-parser/validator.lua:253 -end -- ./lib/lua-parser/validator.lua:253 -status, msg = traverse_block(env, stm[i + 1]) -- ./lib/lua-parser/validator.lua:254 +status, msg = traverse_block(env, stm[i + 1]) -- ./lib/lua-parser/validator.lua:249 +if not status then -- ./lib/lua-parser/validator.lua:250 +return status, msg -- ./lib/lua-parser/validator.lua:250 +end -- ./lib/lua-parser/validator.lua:250 +end -- ./lib/lua-parser/validator.lua:250 +else -- ./lib/lua-parser/validator.lua:250 +for i = 1, len - 1, 2 do -- ./lib/lua-parser/validator.lua:253 +local status, msg = traverse_exp(env, stm[i]) -- ./lib/lua-parser/validator.lua:254 if not status then -- ./lib/lua-parser/validator.lua:255 return status, msg -- ./lib/lua-parser/validator.lua:255 end -- ./lib/lua-parser/validator.lua:255 -end -- ./lib/lua-parser/validator.lua:255 -local status, msg = traverse_block(env, stm[len]) -- ./lib/lua-parser/validator.lua:257 -if not status then -- ./lib/lua-parser/validator.lua:258 -return status, msg -- ./lib/lua-parser/validator.lua:258 -end -- ./lib/lua-parser/validator.lua:258 -end -- ./lib/lua-parser/validator.lua:258 -return true -- ./lib/lua-parser/validator.lua:260 +status, msg = traverse_block(env, stm[i + 1]) -- ./lib/lua-parser/validator.lua:256 +if not status then -- ./lib/lua-parser/validator.lua:257 +return status, msg -- ./lib/lua-parser/validator.lua:257 +end -- ./lib/lua-parser/validator.lua:257 +end -- ./lib/lua-parser/validator.lua:257 +local status, msg = traverse_block(env, stm[len]) -- ./lib/lua-parser/validator.lua:259 +if not status then -- ./lib/lua-parser/validator.lua:260 +return status, msg -- ./lib/lua-parser/validator.lua:260 end -- ./lib/lua-parser/validator.lua:260 -local function traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:263 -local status, msg = set_label(env, stm[1], stm["pos"]) -- ./lib/lua-parser/validator.lua:264 -if not status then -- ./lib/lua-parser/validator.lua:265 -return status, msg -- ./lib/lua-parser/validator.lua:265 -end -- ./lib/lua-parser/validator.lua:265 -return true -- ./lib/lua-parser/validator.lua:266 -end -- ./lib/lua-parser/validator.lua:266 -local function traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:269 -local status, msg = traverse_explist(env, stm[2]) -- ./lib/lua-parser/validator.lua:270 -if not status then -- ./lib/lua-parser/validator.lua:271 -return status, msg -- ./lib/lua-parser/validator.lua:271 -end -- ./lib/lua-parser/validator.lua:271 -return true -- ./lib/lua-parser/validator.lua:272 -end -- ./lib/lua-parser/validator.lua:272 -local function traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:275 -local status, msg = traverse_exp(env, stm[2][1]) -- ./lib/lua-parser/validator.lua:276 -if not status then -- ./lib/lua-parser/validator.lua:277 -return status, msg -- ./lib/lua-parser/validator.lua:277 -end -- ./lib/lua-parser/validator.lua:277 +end -- ./lib/lua-parser/validator.lua:260 +return true -- ./lib/lua-parser/validator.lua:262 +end -- ./lib/lua-parser/validator.lua:262 +local function traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:265 +local status, msg = set_label(env, stm[1], stm["pos"]) -- ./lib/lua-parser/validator.lua:266 +if not status then -- ./lib/lua-parser/validator.lua:267 +return status, msg -- ./lib/lua-parser/validator.lua:267 +end -- ./lib/lua-parser/validator.lua:267 +return true -- ./lib/lua-parser/validator.lua:268 +end -- ./lib/lua-parser/validator.lua:268 +local function traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:271 +begin_loop(env) -- ./lib/lua-parser/validator.lua:272 +local status, msg = traverse_block(env, stm[1]) -- ./lib/lua-parser/validator.lua:273 +if not status then -- ./lib/lua-parser/validator.lua:274 +return status, msg -- ./lib/lua-parser/validator.lua:274 +end -- ./lib/lua-parser/validator.lua:274 +status, msg = traverse_exp(env, stm[2]) -- ./lib/lua-parser/validator.lua:275 +if not status then -- ./lib/lua-parser/validator.lua:276 +return status, msg -- ./lib/lua-parser/validator.lua:276 +end -- ./lib/lua-parser/validator.lua:276 +end_loop(env) -- ./lib/lua-parser/validator.lua:277 return true -- ./lib/lua-parser/validator.lua:278 end -- ./lib/lua-parser/validator.lua:278 -local function traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:281 -begin_loop(env) -- ./lib/lua-parser/validator.lua:282 -local status, msg = traverse_block(env, stm[1]) -- ./lib/lua-parser/validator.lua:283 -if not status then -- ./lib/lua-parser/validator.lua:284 -return status, msg -- ./lib/lua-parser/validator.lua:284 +local function traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:281 +local status, msg = traverse_explist(env, stm) -- ./lib/lua-parser/validator.lua:282 +if not status then -- ./lib/lua-parser/validator.lua:283 +return status, msg -- ./lib/lua-parser/validator.lua:283 +end -- ./lib/lua-parser/validator.lua:283 +return true -- ./lib/lua-parser/validator.lua:284 end -- ./lib/lua-parser/validator.lua:284 -status, msg = traverse_exp(env, stm[2]) -- ./lib/lua-parser/validator.lua:285 -if not status then -- ./lib/lua-parser/validator.lua:286 -return status, msg -- ./lib/lua-parser/validator.lua:286 -end -- ./lib/lua-parser/validator.lua:286 -end_loop(env) -- ./lib/lua-parser/validator.lua:287 -return true -- ./lib/lua-parser/validator.lua:288 -end -- ./lib/lua-parser/validator.lua:288 -local function traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:291 -local status, msg = traverse_explist(env, stm) -- ./lib/lua-parser/validator.lua:292 -if not status then -- ./lib/lua-parser/validator.lua:293 -return status, msg -- ./lib/lua-parser/validator.lua:293 -end -- ./lib/lua-parser/validator.lua:293 +local function traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:287 +begin_loop(env) -- ./lib/lua-parser/validator.lua:288 +local status, msg = traverse_exp(env, stm[1]) -- ./lib/lua-parser/validator.lua:289 +if not status then -- ./lib/lua-parser/validator.lua:290 +return status, msg -- ./lib/lua-parser/validator.lua:290 +end -- ./lib/lua-parser/validator.lua:290 +status, msg = traverse_block(env, stm[2]) -- ./lib/lua-parser/validator.lua:291 +if not status then -- ./lib/lua-parser/validator.lua:292 +return status, msg -- ./lib/lua-parser/validator.lua:292 +end -- ./lib/lua-parser/validator.lua:292 +end_loop(env) -- ./lib/lua-parser/validator.lua:293 return true -- ./lib/lua-parser/validator.lua:294 end -- ./lib/lua-parser/validator.lua:294 -local function traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:297 -begin_loop(env) -- ./lib/lua-parser/validator.lua:298 -local status, msg = traverse_exp(env, stm[1]) -- ./lib/lua-parser/validator.lua:299 -if not status then -- ./lib/lua-parser/validator.lua:300 -return status, msg -- ./lib/lua-parser/validator.lua:300 -end -- ./lib/lua-parser/validator.lua:300 -status, msg = traverse_block(env, stm[2]) -- ./lib/lua-parser/validator.lua:301 -if not status then -- ./lib/lua-parser/validator.lua:302 -return status, msg -- ./lib/lua-parser/validator.lua:302 -end -- ./lib/lua-parser/validator.lua:302 -end_loop(env) -- ./lib/lua-parser/validator.lua:303 -return true -- ./lib/lua-parser/validator.lua:304 -end -- ./lib/lua-parser/validator.lua:304 -traverse_var = function(env, var) -- ./lib/lua-parser/validator.lua:307 -local tag = var["tag"] -- ./lib/lua-parser/validator.lua:308 -if tag == "Id" then -- `Id{ } -- ./lib/lua-parser/validator.lua:309 -return true -- ./lib/lua-parser/validator.lua:310 -elseif tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:311 -local status, msg = traverse_exp(env, var[1]) -- ./lib/lua-parser/validator.lua:312 -if not status then -- ./lib/lua-parser/validator.lua:313 -return status, msg -- ./lib/lua-parser/validator.lua:313 -end -- ./lib/lua-parser/validator.lua:313 -status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:314 +traverse_var = function(env, var) -- ./lib/lua-parser/validator.lua:297 +local tag = var["tag"] -- ./lib/lua-parser/validator.lua:298 +if tag == "Id" then -- `Id{ } -- ./lib/lua-parser/validator.lua:299 +return true -- ./lib/lua-parser/validator.lua:300 +elseif tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:301 +local status, msg = traverse_exp(env, var[1]) -- ./lib/lua-parser/validator.lua:302 +if not status then -- ./lib/lua-parser/validator.lua:303 +return status, msg -- ./lib/lua-parser/validator.lua:303 +end -- ./lib/lua-parser/validator.lua:303 +status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:304 +if not status then -- ./lib/lua-parser/validator.lua:305 +return status, msg -- ./lib/lua-parser/validator.lua:305 +end -- ./lib/lua-parser/validator.lua:305 +return true -- ./lib/lua-parser/validator.lua:306 +else -- ./lib/lua-parser/validator.lua:306 +error("expecting a variable, but got a " .. tag) -- ./lib/lua-parser/validator.lua:308 +end -- ./lib/lua-parser/validator.lua:308 +end -- ./lib/lua-parser/validator.lua:308 +traverse_varlist = function(env, varlist) -- ./lib/lua-parser/validator.lua:312 +for k, v in ipairs(varlist) do -- ./lib/lua-parser/validator.lua:313 +local status, msg = traverse_var(env, v) -- ./lib/lua-parser/validator.lua:314 if not status then -- ./lib/lua-parser/validator.lua:315 return status, msg -- ./lib/lua-parser/validator.lua:315 end -- ./lib/lua-parser/validator.lua:315 -return true -- ./lib/lua-parser/validator.lua:316 -else -- ./lib/lua-parser/validator.lua:316 -error("expecting a variable, but got a " .. tag) -- ./lib/lua-parser/validator.lua:318 -end -- ./lib/lua-parser/validator.lua:318 -end -- ./lib/lua-parser/validator.lua:318 -traverse_varlist = function(env, varlist) -- ./lib/lua-parser/validator.lua:322 -for k, v in ipairs(varlist) do -- ./lib/lua-parser/validator.lua:323 -local status, msg = traverse_var(env, v) -- ./lib/lua-parser/validator.lua:324 -if not status then -- ./lib/lua-parser/validator.lua:325 -return status, msg -- ./lib/lua-parser/validator.lua:325 +end -- ./lib/lua-parser/validator.lua:315 +return true -- ./lib/lua-parser/validator.lua:317 +end -- ./lib/lua-parser/validator.lua:317 +local function traverse_methodstub(env, var) -- ./lib/lua-parser/validator.lua:320 +local status, msg = traverse_exp(env, var[1]) -- ./lib/lua-parser/validator.lua:321 +if not status then -- ./lib/lua-parser/validator.lua:322 +return status, msg -- ./lib/lua-parser/validator.lua:322 +end -- ./lib/lua-parser/validator.lua:322 +status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:323 +if not status then -- ./lib/lua-parser/validator.lua:324 +return status, msg -- ./lib/lua-parser/validator.lua:324 +end -- ./lib/lua-parser/validator.lua:324 +return true -- ./lib/lua-parser/validator.lua:325 end -- ./lib/lua-parser/validator.lua:325 -end -- ./lib/lua-parser/validator.lua:325 -return true -- ./lib/lua-parser/validator.lua:327 -end -- ./lib/lua-parser/validator.lua:327 -traverse_exp = function(env, exp) -- ./lib/lua-parser/validator.lua:330 -local tag = exp["tag"] -- ./lib/lua-parser/validator.lua:331 -if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- `String{ } -- ./lib/lua-parser/validator.lua:335 -return true -- ./lib/lua-parser/validator.lua:336 -elseif tag == "Dots" then -- ./lib/lua-parser/validator.lua:337 -return traverse_vararg(env, exp) -- ./lib/lua-parser/validator.lua:338 -elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } -- ./lib/lua-parser/validator.lua:339 -return traverse_function(env, exp) -- ./lib/lua-parser/validator.lua:340 -elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } -- ./lib/lua-parser/validator.lua:341 -return traverse_table(env, exp) -- ./lib/lua-parser/validator.lua:342 -elseif tag == "Op" then -- `Op{ opid expr expr? } -- ./lib/lua-parser/validator.lua:343 -return traverse_op(env, exp) -- ./lib/lua-parser/validator.lua:344 -elseif tag == "Paren" then -- `Paren{ expr } -- ./lib/lua-parser/validator.lua:345 -return traverse_paren(env, exp) -- ./lib/lua-parser/validator.lua:346 -elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/validator.lua:347 -return traverse_call(env, exp) -- ./lib/lua-parser/validator.lua:348 -elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } -- ./lib/lua-parser/validator.lua:349 -return traverse_invoke(env, exp) -- ./lib/lua-parser/validator.lua:350 -elseif tag == "Id" or tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:352 -return traverse_var(env, exp) -- ./lib/lua-parser/validator.lua:353 -elseif tag == "TableCompr" then -- `TableCompr{ block } -- ./lib/lua-parser/validator.lua:354 -return traverse_tablecompr(env, exp) -- ./lib/lua-parser/validator.lua:355 -elseif tag:match("Expr$") then -- `StatExpr{ ... } -- ./lib/lua-parser/validator.lua:356 -return traverse_statexpr(env, exp) -- ./lib/lua-parser/validator.lua:357 -else -- ./lib/lua-parser/validator.lua:357 -error("expecting an expression, but got a " .. tag) -- ./lib/lua-parser/validator.lua:359 -end -- ./lib/lua-parser/validator.lua:359 -end -- ./lib/lua-parser/validator.lua:359 -traverse_explist = function(env, explist) -- ./lib/lua-parser/validator.lua:363 -for k, v in ipairs(explist) do -- ./lib/lua-parser/validator.lua:364 -local status, msg = traverse_exp(env, v) -- ./lib/lua-parser/validator.lua:365 -if not status then -- ./lib/lua-parser/validator.lua:366 -return status, msg -- ./lib/lua-parser/validator.lua:366 -end -- ./lib/lua-parser/validator.lua:366 -end -- ./lib/lua-parser/validator.lua:366 -return true -- ./lib/lua-parser/validator.lua:368 -end -- ./lib/lua-parser/validator.lua:368 -traverse_stm = function(env, stm) -- ./lib/lua-parser/validator.lua:371 -local tag = stm["tag"] -- ./lib/lua-parser/validator.lua:372 -if tag == "Do" then -- `Do{ stat* } -- ./lib/lua-parser/validator.lua:373 -return traverse_block(env, stm) -- ./lib/lua-parser/validator.lua:374 -elseif tag == "Set" then -- `Set{ {lhs+} (opid? = opid?)? {expr+} } -- ./lib/lua-parser/validator.lua:375 -return traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:376 -elseif tag == "While" then -- `While{ expr block } -- ./lib/lua-parser/validator.lua:377 -return traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:378 -elseif tag == "Repeat" then -- `Repeat{ block expr } -- ./lib/lua-parser/validator.lua:379 -return traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:380 -elseif tag == "If" then -- `If{ (expr block)+ block? } -- ./lib/lua-parser/validator.lua:381 -return traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:382 -elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } -- ./lib/lua-parser/validator.lua:383 -return traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:384 -elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } -- ./lib/lua-parser/validator.lua:385 -return traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:386 -elseif tag == "Local" or tag == "Let" then -- `Let{ {ident+} {expr+}? } -- ./lib/lua-parser/validator.lua:388 -return traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:389 -elseif tag == "Localrec" then -- `Localrec{ ident expr } -- ./lib/lua-parser/validator.lua:390 -return traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:391 -elseif tag == "Goto" then -- `Goto{ } -- ./lib/lua-parser/validator.lua:392 -return traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:393 -elseif tag == "Label" then -- `Label{ } -- ./lib/lua-parser/validator.lua:394 -return traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:395 -elseif tag == "Return" then -- `Return{ * } -- ./lib/lua-parser/validator.lua:396 -return traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:397 -elseif tag == "Break" then -- ./lib/lua-parser/validator.lua:398 -return traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:399 -elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/validator.lua:400 -return traverse_call(env, stm) -- ./lib/lua-parser/validator.lua:401 -elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } -- ./lib/lua-parser/validator.lua:402 -return traverse_invoke(env, stm) -- ./lib/lua-parser/validator.lua:403 -elseif tag == "Continue" then -- ./lib/lua-parser/validator.lua:404 -return traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:405 -elseif tag == "Push" then -- `Push{ * } -- ./lib/lua-parser/validator.lua:406 -return traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:407 -else -- ./lib/lua-parser/validator.lua:407 -error("expecting a statement, but got a " .. tag) -- ./lib/lua-parser/validator.lua:409 -end -- ./lib/lua-parser/validator.lua:409 -end -- ./lib/lua-parser/validator.lua:409 -traverse_block = function(env, block) -- ./lib/lua-parser/validator.lua:413 -local l = {} -- ./lib/lua-parser/validator.lua:414 -new_scope(env) -- ./lib/lua-parser/validator.lua:415 -for k, v in ipairs(block) do -- ./lib/lua-parser/validator.lua:416 -local status, msg = traverse_stm(env, v) -- ./lib/lua-parser/validator.lua:417 -if not status then -- ./lib/lua-parser/validator.lua:418 -return status, msg -- ./lib/lua-parser/validator.lua:418 -end -- ./lib/lua-parser/validator.lua:418 -end -- ./lib/lua-parser/validator.lua:418 -end_scope(env) -- ./lib/lua-parser/validator.lua:420 -return true -- ./lib/lua-parser/validator.lua:421 -end -- ./lib/lua-parser/validator.lua:421 -local function traverse(ast, errorinfo) -- ./lib/lua-parser/validator.lua:425 -assert(type(ast) == "table") -- ./lib/lua-parser/validator.lua:426 -assert(type(errorinfo) == "table") -- ./lib/lua-parser/validator.lua:427 -local env = { -- ./lib/lua-parser/validator.lua:428 -["errorinfo"] = errorinfo, -- ./lib/lua-parser/validator.lua:428 -["function"] = {} -- ./lib/lua-parser/validator.lua:428 -} -- ./lib/lua-parser/validator.lua:428 -new_function(env) -- ./lib/lua-parser/validator.lua:429 -set_vararg(env, true) -- ./lib/lua-parser/validator.lua:430 -local status, msg = traverse_block(env, ast) -- ./lib/lua-parser/validator.lua:431 -if not status then -- ./lib/lua-parser/validator.lua:432 -return status, msg -- ./lib/lua-parser/validator.lua:432 -end -- ./lib/lua-parser/validator.lua:432 -end_function(env) -- ./lib/lua-parser/validator.lua:433 -status, msg = verify_pending_gotos(env) -- ./lib/lua-parser/validator.lua:434 -if not status then -- ./lib/lua-parser/validator.lua:435 -return status, msg -- ./lib/lua-parser/validator.lua:435 -end -- ./lib/lua-parser/validator.lua:435 -return ast -- ./lib/lua-parser/validator.lua:436 -end -- ./lib/lua-parser/validator.lua:436 -return { -- ./lib/lua-parser/validator.lua:439 -["validate"] = traverse, -- ./lib/lua-parser/validator.lua:439 -["syntaxerror"] = syntaxerror -- ./lib/lua-parser/validator.lua:439 -} -- ./lib/lua-parser/validator.lua:439 -end -- ./lib/lua-parser/validator.lua:439 -local validator = _() or validator -- ./lib/lua-parser/validator.lua:443 -package["loaded"]["lib.lua-parser.validator"] = validator or true -- ./lib/lua-parser/validator.lua:444 -local function _() -- ./lib/lua-parser/validator.lua:447 +local function traverse_safeindex(env, var) -- ./lib/lua-parser/validator.lua:328 +local status, msg = traverse_exp(env, var[1]) -- ./lib/lua-parser/validator.lua:329 +if not status then -- ./lib/lua-parser/validator.lua:330 +return status, msg -- ./lib/lua-parser/validator.lua:330 +end -- ./lib/lua-parser/validator.lua:330 +status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:331 +if not status then -- ./lib/lua-parser/validator.lua:332 +return status, msg -- ./lib/lua-parser/validator.lua:332 +end -- ./lib/lua-parser/validator.lua:332 +return true -- ./lib/lua-parser/validator.lua:333 +end -- ./lib/lua-parser/validator.lua:333 +traverse_exp = function(env, exp) -- ./lib/lua-parser/validator.lua:336 +local tag = exp["tag"] -- ./lib/lua-parser/validator.lua:337 +if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- `String{ } -- ./lib/lua-parser/validator.lua:341 +return true -- ./lib/lua-parser/validator.lua:342 +elseif tag == "Dots" then -- ./lib/lua-parser/validator.lua:343 +return traverse_vararg(env, exp) -- ./lib/lua-parser/validator.lua:344 +elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } -- ./lib/lua-parser/validator.lua:345 +return traverse_function(env, exp) -- ./lib/lua-parser/validator.lua:346 +elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } -- ./lib/lua-parser/validator.lua:347 +return traverse_table(env, exp) -- ./lib/lua-parser/validator.lua:348 +elseif tag == "Op" then -- `Op{ opid expr expr? } -- ./lib/lua-parser/validator.lua:349 +return traverse_op(env, exp) -- ./lib/lua-parser/validator.lua:350 +elseif tag == "Paren" then -- `Paren{ expr } -- ./lib/lua-parser/validator.lua:351 +return traverse_paren(env, exp) -- ./lib/lua-parser/validator.lua:352 +elseif tag == "Call" or tag == "SafeCall" then -- `(Safe)Call{ expr expr* } -- ./lib/lua-parser/validator.lua:353 +return traverse_call(env, exp) -- ./lib/lua-parser/validator.lua:354 +elseif tag == "Id" or tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:356 +return traverse_var(env, exp) -- ./lib/lua-parser/validator.lua:357 +elseif tag == "SafeIndex" then -- `SafeIndex{ expr expr } -- ./lib/lua-parser/validator.lua:358 +return traverse_safeindex(env, exp) -- ./lib/lua-parser/validator.lua:359 +elseif tag == "TableCompr" then -- `TableCompr{ block } -- ./lib/lua-parser/validator.lua:360 +return traverse_tablecompr(env, exp) -- ./lib/lua-parser/validator.lua:361 +elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- `(Safe)MethodStub{ expr expr } -- ./lib/lua-parser/validator.lua:362 +return traverse_methodstub(env, exp) -- ./lib/lua-parser/validator.lua:363 +elseif tag:match("Expr$") then -- `StatExpr{ ... } -- ./lib/lua-parser/validator.lua:364 +return traverse_statexpr(env, exp) -- ./lib/lua-parser/validator.lua:365 +else -- ./lib/lua-parser/validator.lua:365 +error("expecting an expression, but got a " .. tag) -- ./lib/lua-parser/validator.lua:367 +end -- ./lib/lua-parser/validator.lua:367 +end -- ./lib/lua-parser/validator.lua:367 +traverse_explist = function(env, explist) -- ./lib/lua-parser/validator.lua:371 +for k, v in ipairs(explist) do -- ./lib/lua-parser/validator.lua:372 +local status, msg = traverse_exp(env, v) -- ./lib/lua-parser/validator.lua:373 +if not status then -- ./lib/lua-parser/validator.lua:374 +return status, msg -- ./lib/lua-parser/validator.lua:374 +end -- ./lib/lua-parser/validator.lua:374 +end -- ./lib/lua-parser/validator.lua:374 +return true -- ./lib/lua-parser/validator.lua:376 +end -- ./lib/lua-parser/validator.lua:376 +traverse_stm = function(env, stm) -- ./lib/lua-parser/validator.lua:379 +local tag = stm["tag"] -- ./lib/lua-parser/validator.lua:380 +if tag == "Do" then -- `Do{ stat* } -- ./lib/lua-parser/validator.lua:381 +return traverse_block(env, stm) -- ./lib/lua-parser/validator.lua:382 +elseif tag == "Set" then -- `Set{ {lhs+} (opid? = opid?)? {expr+} } -- ./lib/lua-parser/validator.lua:383 +return traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:384 +elseif tag == "While" then -- `While{ expr block } -- ./lib/lua-parser/validator.lua:385 +return traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:386 +elseif tag == "Repeat" then -- `Repeat{ block expr } -- ./lib/lua-parser/validator.lua:387 +return traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:388 +elseif tag == "If" then -- `If{ (expr block)+ block? } -- ./lib/lua-parser/validator.lua:389 +return traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:390 +elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } -- ./lib/lua-parser/validator.lua:391 +return traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:392 +elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } -- ./lib/lua-parser/validator.lua:393 +return traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:394 +elseif tag == "Local" or tag == "Let" then -- `Let{ {ident+} {expr+}? } -- ./lib/lua-parser/validator.lua:396 +return traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:397 +elseif tag == "Localrec" then -- `Localrec{ ident expr } -- ./lib/lua-parser/validator.lua:398 +return traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:399 +elseif tag == "Goto" then -- `Goto{ } -- ./lib/lua-parser/validator.lua:400 +return traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:401 +elseif tag == "Label" then -- `Label{ } -- ./lib/lua-parser/validator.lua:402 +return traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:403 +elseif tag == "Return" then -- `Return{ * } -- ./lib/lua-parser/validator.lua:404 +return traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:405 +elseif tag == "Break" then -- ./lib/lua-parser/validator.lua:406 +return traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:407 +elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/validator.lua:408 +return traverse_call(env, stm) -- ./lib/lua-parser/validator.lua:409 +elseif tag == "Continue" then -- ./lib/lua-parser/validator.lua:410 +return traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:411 +elseif tag == "Push" then -- `Push{ * } -- ./lib/lua-parser/validator.lua:412 +return traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:413 +else -- ./lib/lua-parser/validator.lua:413 +error("expecting a statement, but got a " .. tag) -- ./lib/lua-parser/validator.lua:415 +end -- ./lib/lua-parser/validator.lua:415 +end -- ./lib/lua-parser/validator.lua:415 +traverse_block = function(env, block) -- ./lib/lua-parser/validator.lua:419 +local l = {} -- ./lib/lua-parser/validator.lua:420 +new_scope(env) -- ./lib/lua-parser/validator.lua:421 +for k, v in ipairs(block) do -- ./lib/lua-parser/validator.lua:422 +local status, msg = traverse_stm(env, v) -- ./lib/lua-parser/validator.lua:423 +if not status then -- ./lib/lua-parser/validator.lua:424 +return status, msg -- ./lib/lua-parser/validator.lua:424 +end -- ./lib/lua-parser/validator.lua:424 +end -- ./lib/lua-parser/validator.lua:424 +end_scope(env) -- ./lib/lua-parser/validator.lua:426 +return true -- ./lib/lua-parser/validator.lua:427 +end -- ./lib/lua-parser/validator.lua:427 +local function traverse(ast, errorinfo) -- ./lib/lua-parser/validator.lua:431 +assert(type(ast) == "table") -- ./lib/lua-parser/validator.lua:432 +assert(type(errorinfo) == "table") -- ./lib/lua-parser/validator.lua:433 +local env = { -- ./lib/lua-parser/validator.lua:434 +["errorinfo"] = errorinfo, -- ./lib/lua-parser/validator.lua:434 +["function"] = {} -- ./lib/lua-parser/validator.lua:434 +} -- ./lib/lua-parser/validator.lua:434 +new_function(env) -- ./lib/lua-parser/validator.lua:435 +set_vararg(env, true) -- ./lib/lua-parser/validator.lua:436 +local status, msg = traverse_block(env, ast) -- ./lib/lua-parser/validator.lua:437 +if not status then -- ./lib/lua-parser/validator.lua:438 +return status, msg -- ./lib/lua-parser/validator.lua:438 +end -- ./lib/lua-parser/validator.lua:438 +end_function(env) -- ./lib/lua-parser/validator.lua:439 +status, msg = verify_pending_gotos(env) -- ./lib/lua-parser/validator.lua:440 +if not status then -- ./lib/lua-parser/validator.lua:441 +return status, msg -- ./lib/lua-parser/validator.lua:441 +end -- ./lib/lua-parser/validator.lua:441 +return ast -- ./lib/lua-parser/validator.lua:442 +end -- ./lib/lua-parser/validator.lua:442 +return { -- ./lib/lua-parser/validator.lua:445 +["validate"] = traverse, -- ./lib/lua-parser/validator.lua:445 +["syntaxerror"] = syntaxerror -- ./lib/lua-parser/validator.lua:445 +} -- ./lib/lua-parser/validator.lua:445 +end -- ./lib/lua-parser/validator.lua:445 +local validator = _() or validator -- ./lib/lua-parser/validator.lua:449 +package["loaded"]["lib.lua-parser.validator"] = validator or true -- ./lib/lua-parser/validator.lua:450 +local function _() -- ./lib/lua-parser/validator.lua:453 local pp = {} -- ./lib/lua-parser/pp.lua:4 local block2str, stm2str, exp2str, var2str -- ./lib/lua-parser/pp.lua:6 local explist2str, varlist2str, parlist2str, fieldlist2str -- ./lib/lua-parser/pp.lua:7 @@ -2850,740 +3230,778 @@ end -- ./lib/lua-parser/pp.lua:327 local pp = _() or pp -- ./lib/lua-parser/pp.lua:331 package["loaded"]["lib.lua-parser.pp"] = pp or true -- ./lib/lua-parser/pp.lua:332 local function _() -- ./lib/lua-parser/pp.lua:335 -local lpeg = require("lpeglabel") -- ./lib/lua-parser/parser.lua:65 -lpeg["locale"](lpeg) -- ./lib/lua-parser/parser.lua:67 -local P, S, V = lpeg["P"], lpeg["S"], lpeg["V"] -- ./lib/lua-parser/parser.lua:69 -local C, Carg, Cb, Cc = lpeg["C"], lpeg["Carg"], lpeg["Cb"], lpeg["Cc"] -- ./lib/lua-parser/parser.lua:70 -local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg["Cf"], lpeg["Cg"], lpeg["Cmt"], lpeg["Cp"], lpeg["Cs"], lpeg["Ct"] -- ./lib/lua-parser/parser.lua:71 -local Rec, T = lpeg["Rec"], lpeg["T"] -- ./lib/lua-parser/parser.lua:72 -local alpha, digit, alnum = lpeg["alpha"], lpeg["digit"], lpeg["alnum"] -- ./lib/lua-parser/parser.lua:74 -local xdigit = lpeg["xdigit"] -- ./lib/lua-parser/parser.lua:75 -local space = lpeg["space"] -- ./lib/lua-parser/parser.lua:76 -local labels = { -- ./lib/lua-parser/parser.lua:81 -{ -- ./lib/lua-parser/parser.lua:82 -"ErrExtra", -- ./lib/lua-parser/parser.lua:82 -"unexpected character(s), expected EOF" -- ./lib/lua-parser/parser.lua:82 -}, -- ./lib/lua-parser/parser.lua:82 -{ -- ./lib/lua-parser/parser.lua:83 -"ErrInvalidStat", -- ./lib/lua-parser/parser.lua:83 -"unexpected token, invalid start of statement" -- ./lib/lua-parser/parser.lua:83 -}, -- ./lib/lua-parser/parser.lua:83 -{ -- ./lib/lua-parser/parser.lua:85 -"ErrEndIf", -- ./lib/lua-parser/parser.lua:85 -"expected 'end' to close the if statement" -- ./lib/lua-parser/parser.lua:85 -}, -- ./lib/lua-parser/parser.lua:85 -{ -- ./lib/lua-parser/parser.lua:86 -"ErrExprIf", -- ./lib/lua-parser/parser.lua:86 -"expected a condition after 'if'" -- ./lib/lua-parser/parser.lua:86 -}, -- ./lib/lua-parser/parser.lua:86 -{ -- ./lib/lua-parser/parser.lua:87 -"ErrThenIf", -- ./lib/lua-parser/parser.lua:87 -"expected 'then' after the condition" -- ./lib/lua-parser/parser.lua:87 -}, -- ./lib/lua-parser/parser.lua:87 -{ -- ./lib/lua-parser/parser.lua:88 -"ErrExprEIf", -- ./lib/lua-parser/parser.lua:88 -"expected a condition after 'elseif'" -- ./lib/lua-parser/parser.lua:88 -}, -- ./lib/lua-parser/parser.lua:88 +local lpeg = require("lpeglabel") -- ./lib/lua-parser/parser.lua:72 +lpeg["locale"](lpeg) -- ./lib/lua-parser/parser.lua:74 +local P, S, V = lpeg["P"], lpeg["S"], lpeg["V"] -- ./lib/lua-parser/parser.lua:76 +local C, Carg, Cb, Cc = lpeg["C"], lpeg["Carg"], lpeg["Cb"], lpeg["Cc"] -- ./lib/lua-parser/parser.lua:77 +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg["Cf"], lpeg["Cg"], lpeg["Cmt"], lpeg["Cp"], lpeg["Cs"], lpeg["Ct"] -- ./lib/lua-parser/parser.lua:78 +local Rec, T = lpeg["Rec"], lpeg["T"] -- ./lib/lua-parser/parser.lua:79 +local alpha, digit, alnum = lpeg["alpha"], lpeg["digit"], lpeg["alnum"] -- ./lib/lua-parser/parser.lua:81 +local xdigit = lpeg["xdigit"] -- ./lib/lua-parser/parser.lua:82 +local space = lpeg["space"] -- ./lib/lua-parser/parser.lua:83 +local labels = { -- ./lib/lua-parser/parser.lua:88 { -- ./lib/lua-parser/parser.lua:89 -"ErrThenEIf", -- ./lib/lua-parser/parser.lua:89 -"expected 'then' after the condition" -- ./lib/lua-parser/parser.lua:89 +"ErrExtra", -- ./lib/lua-parser/parser.lua:89 +"unexpected character(s), expected EOF" -- ./lib/lua-parser/parser.lua:89 }, -- ./lib/lua-parser/parser.lua:89 -{ -- ./lib/lua-parser/parser.lua:91 -"ErrEndDo", -- ./lib/lua-parser/parser.lua:91 -"expected 'end' to close the do block" -- ./lib/lua-parser/parser.lua:91 -}, -- ./lib/lua-parser/parser.lua:91 +{ -- ./lib/lua-parser/parser.lua:90 +"ErrInvalidStat", -- ./lib/lua-parser/parser.lua:90 +"unexpected token, invalid start of statement" -- ./lib/lua-parser/parser.lua:90 +}, -- ./lib/lua-parser/parser.lua:90 { -- ./lib/lua-parser/parser.lua:92 -"ErrExprWhile", -- ./lib/lua-parser/parser.lua:92 -"expected a condition after 'while'" -- ./lib/lua-parser/parser.lua:92 +"ErrEndIf", -- ./lib/lua-parser/parser.lua:92 +"expected 'end' to close the if statement" -- ./lib/lua-parser/parser.lua:92 }, -- ./lib/lua-parser/parser.lua:92 { -- ./lib/lua-parser/parser.lua:93 -"ErrDoWhile", -- ./lib/lua-parser/parser.lua:93 -"expected 'do' after the condition" -- ./lib/lua-parser/parser.lua:93 +"ErrExprIf", -- ./lib/lua-parser/parser.lua:93 +"expected a condition after 'if'" -- ./lib/lua-parser/parser.lua:93 }, -- ./lib/lua-parser/parser.lua:93 { -- ./lib/lua-parser/parser.lua:94 -"ErrEndWhile", -- ./lib/lua-parser/parser.lua:94 -"expected 'end' to close the while loop" -- ./lib/lua-parser/parser.lua:94 +"ErrThenIf", -- ./lib/lua-parser/parser.lua:94 +"expected 'then' after the condition" -- ./lib/lua-parser/parser.lua:94 }, -- ./lib/lua-parser/parser.lua:94 { -- ./lib/lua-parser/parser.lua:95 -"ErrUntilRep", -- ./lib/lua-parser/parser.lua:95 -"expected 'until' at the end of the repeat loop" -- ./lib/lua-parser/parser.lua:95 +"ErrExprEIf", -- ./lib/lua-parser/parser.lua:95 +"expected a condition after 'elseif'" -- ./lib/lua-parser/parser.lua:95 }, -- ./lib/lua-parser/parser.lua:95 { -- ./lib/lua-parser/parser.lua:96 -"ErrExprRep", -- ./lib/lua-parser/parser.lua:96 -"expected a conditions after 'until'" -- ./lib/lua-parser/parser.lua:96 +"ErrThenEIf", -- ./lib/lua-parser/parser.lua:96 +"expected 'then' after the condition" -- ./lib/lua-parser/parser.lua:96 }, -- ./lib/lua-parser/parser.lua:96 { -- ./lib/lua-parser/parser.lua:98 -"ErrForRange", -- ./lib/lua-parser/parser.lua:98 -"expected a numeric or generic range after 'for'" -- ./lib/lua-parser/parser.lua:98 +"ErrEndDo", -- ./lib/lua-parser/parser.lua:98 +"expected 'end' to close the do block" -- ./lib/lua-parser/parser.lua:98 }, -- ./lib/lua-parser/parser.lua:98 { -- ./lib/lua-parser/parser.lua:99 -"ErrEndFor", -- ./lib/lua-parser/parser.lua:99 -"expected 'end' to close the for loop" -- ./lib/lua-parser/parser.lua:99 +"ErrExprWhile", -- ./lib/lua-parser/parser.lua:99 +"expected a condition after 'while'" -- ./lib/lua-parser/parser.lua:99 }, -- ./lib/lua-parser/parser.lua:99 { -- ./lib/lua-parser/parser.lua:100 -"ErrExprFor1", -- ./lib/lua-parser/parser.lua:100 -"expected a starting expression for the numeric range" -- ./lib/lua-parser/parser.lua:100 +"ErrDoWhile", -- ./lib/lua-parser/parser.lua:100 +"expected 'do' after the condition" -- ./lib/lua-parser/parser.lua:100 }, -- ./lib/lua-parser/parser.lua:100 { -- ./lib/lua-parser/parser.lua:101 -"ErrCommaFor", -- ./lib/lua-parser/parser.lua:101 -"expected ',' to split the start and end of the range" -- ./lib/lua-parser/parser.lua:101 +"ErrEndWhile", -- ./lib/lua-parser/parser.lua:101 +"expected 'end' to close the while loop" -- ./lib/lua-parser/parser.lua:101 }, -- ./lib/lua-parser/parser.lua:101 { -- ./lib/lua-parser/parser.lua:102 -"ErrExprFor2", -- ./lib/lua-parser/parser.lua:102 -"expected an ending expression for the numeric range" -- ./lib/lua-parser/parser.lua:102 +"ErrUntilRep", -- ./lib/lua-parser/parser.lua:102 +"expected 'until' at the end of the repeat loop" -- ./lib/lua-parser/parser.lua:102 }, -- ./lib/lua-parser/parser.lua:102 { -- ./lib/lua-parser/parser.lua:103 -"ErrExprFor3", -- ./lib/lua-parser/parser.lua:103 -"expected a step expression for the numeric range after ','" -- ./lib/lua-parser/parser.lua:103 +"ErrExprRep", -- ./lib/lua-parser/parser.lua:103 +"expected a conditions after 'until'" -- ./lib/lua-parser/parser.lua:103 }, -- ./lib/lua-parser/parser.lua:103 -{ -- ./lib/lua-parser/parser.lua:104 -"ErrInFor", -- ./lib/lua-parser/parser.lua:104 -"expected '=' or 'in' after the variable(s)" -- ./lib/lua-parser/parser.lua:104 -}, -- ./lib/lua-parser/parser.lua:104 { -- ./lib/lua-parser/parser.lua:105 -"ErrEListFor", -- ./lib/lua-parser/parser.lua:105 -"expected one or more expressions after 'in'" -- ./lib/lua-parser/parser.lua:105 +"ErrForRange", -- ./lib/lua-parser/parser.lua:105 +"expected a numeric or generic range after 'for'" -- ./lib/lua-parser/parser.lua:105 }, -- ./lib/lua-parser/parser.lua:105 { -- ./lib/lua-parser/parser.lua:106 -"ErrDoFor", -- ./lib/lua-parser/parser.lua:106 -"expected 'do' after the range of the for loop" -- ./lib/lua-parser/parser.lua:106 +"ErrEndFor", -- ./lib/lua-parser/parser.lua:106 +"expected 'end' to close the for loop" -- ./lib/lua-parser/parser.lua:106 }, -- ./lib/lua-parser/parser.lua:106 +{ -- ./lib/lua-parser/parser.lua:107 +"ErrExprFor1", -- ./lib/lua-parser/parser.lua:107 +"expected a starting expression for the numeric range" -- ./lib/lua-parser/parser.lua:107 +}, -- ./lib/lua-parser/parser.lua:107 { -- ./lib/lua-parser/parser.lua:108 -"ErrDefLocal", -- ./lib/lua-parser/parser.lua:108 -"expected a function definition or assignment after local" -- ./lib/lua-parser/parser.lua:108 +"ErrCommaFor", -- ./lib/lua-parser/parser.lua:108 +"expected ',' to split the start and end of the range" -- ./lib/lua-parser/parser.lua:108 }, -- ./lib/lua-parser/parser.lua:108 { -- ./lib/lua-parser/parser.lua:109 -"ErrDefLet", -- ./lib/lua-parser/parser.lua:109 -"expected a function definition or assignment after let" -- ./lib/lua-parser/parser.lua:109 +"ErrExprFor2", -- ./lib/lua-parser/parser.lua:109 +"expected an ending expression for the numeric range" -- ./lib/lua-parser/parser.lua:109 }, -- ./lib/lua-parser/parser.lua:109 { -- ./lib/lua-parser/parser.lua:110 -"ErrNameLFunc", -- ./lib/lua-parser/parser.lua:110 -"expected a function name after 'function'" -- ./lib/lua-parser/parser.lua:110 +"ErrExprFor3", -- ./lib/lua-parser/parser.lua:110 +"expected a step expression for the numeric range after ','" -- ./lib/lua-parser/parser.lua:110 }, -- ./lib/lua-parser/parser.lua:110 { -- ./lib/lua-parser/parser.lua:111 -"ErrEListLAssign", -- ./lib/lua-parser/parser.lua:111 -"expected one or more expressions after '='" -- ./lib/lua-parser/parser.lua:111 +"ErrInFor", -- ./lib/lua-parser/parser.lua:111 +"expected '=' or 'in' after the variable(s)" -- ./lib/lua-parser/parser.lua:111 }, -- ./lib/lua-parser/parser.lua:111 { -- ./lib/lua-parser/parser.lua:112 -"ErrEListAssign", -- ./lib/lua-parser/parser.lua:112 -"expected one or more expressions after '='" -- ./lib/lua-parser/parser.lua:112 +"ErrEListFor", -- ./lib/lua-parser/parser.lua:112 +"expected one or more expressions after 'in'" -- ./lib/lua-parser/parser.lua:112 }, -- ./lib/lua-parser/parser.lua:112 -{ -- ./lib/lua-parser/parser.lua:114 -"ErrFuncName", -- ./lib/lua-parser/parser.lua:114 -"expected a function name after 'function'" -- ./lib/lua-parser/parser.lua:114 -}, -- ./lib/lua-parser/parser.lua:114 +{ -- ./lib/lua-parser/parser.lua:113 +"ErrDoFor", -- ./lib/lua-parser/parser.lua:113 +"expected 'do' after the range of the for loop" -- ./lib/lua-parser/parser.lua:113 +}, -- ./lib/lua-parser/parser.lua:113 { -- ./lib/lua-parser/parser.lua:115 -"ErrNameFunc1", -- ./lib/lua-parser/parser.lua:115 -"expected a function name after '.'" -- ./lib/lua-parser/parser.lua:115 +"ErrDefLocal", -- ./lib/lua-parser/parser.lua:115 +"expected a function definition or assignment after local" -- ./lib/lua-parser/parser.lua:115 }, -- ./lib/lua-parser/parser.lua:115 { -- ./lib/lua-parser/parser.lua:116 -"ErrNameFunc2", -- ./lib/lua-parser/parser.lua:116 -"expected a method name after ':'" -- ./lib/lua-parser/parser.lua:116 +"ErrDefLet", -- ./lib/lua-parser/parser.lua:116 +"expected a function definition or assignment after let" -- ./lib/lua-parser/parser.lua:116 }, -- ./lib/lua-parser/parser.lua:116 { -- ./lib/lua-parser/parser.lua:117 -"ErrOParenPList", -- ./lib/lua-parser/parser.lua:117 -"expected '(' for the parameter list" -- ./lib/lua-parser/parser.lua:117 +"ErrNameLFunc", -- ./lib/lua-parser/parser.lua:117 +"expected a function name after 'function'" -- ./lib/lua-parser/parser.lua:117 }, -- ./lib/lua-parser/parser.lua:117 { -- ./lib/lua-parser/parser.lua:118 -"ErrCParenPList", -- ./lib/lua-parser/parser.lua:118 -"expected ')' to close the parameter list" -- ./lib/lua-parser/parser.lua:118 +"ErrEListLAssign", -- ./lib/lua-parser/parser.lua:118 +"expected one or more expressions after '='" -- ./lib/lua-parser/parser.lua:118 }, -- ./lib/lua-parser/parser.lua:118 { -- ./lib/lua-parser/parser.lua:119 -"ErrEndFunc", -- ./lib/lua-parser/parser.lua:119 -"expected 'end' to close the function body" -- ./lib/lua-parser/parser.lua:119 +"ErrEListAssign", -- ./lib/lua-parser/parser.lua:119 +"expected one or more expressions after '='" -- ./lib/lua-parser/parser.lua:119 }, -- ./lib/lua-parser/parser.lua:119 -{ -- ./lib/lua-parser/parser.lua:120 -"ErrParList", -- ./lib/lua-parser/parser.lua:120 -"expected a variable name or '...' after ','" -- ./lib/lua-parser/parser.lua:120 -}, -- ./lib/lua-parser/parser.lua:120 +{ -- ./lib/lua-parser/parser.lua:121 +"ErrFuncName", -- ./lib/lua-parser/parser.lua:121 +"expected a function name after 'function'" -- ./lib/lua-parser/parser.lua:121 +}, -- ./lib/lua-parser/parser.lua:121 { -- ./lib/lua-parser/parser.lua:122 -"ErrLabel", -- ./lib/lua-parser/parser.lua:122 -"expected a label name after '::'" -- ./lib/lua-parser/parser.lua:122 +"ErrNameFunc1", -- ./lib/lua-parser/parser.lua:122 +"expected a function name after '.'" -- ./lib/lua-parser/parser.lua:122 }, -- ./lib/lua-parser/parser.lua:122 { -- ./lib/lua-parser/parser.lua:123 -"ErrCloseLabel", -- ./lib/lua-parser/parser.lua:123 -"expected '::' after the label" -- ./lib/lua-parser/parser.lua:123 +"ErrNameFunc2", -- ./lib/lua-parser/parser.lua:123 +"expected a method name after ':'" -- ./lib/lua-parser/parser.lua:123 }, -- ./lib/lua-parser/parser.lua:123 { -- ./lib/lua-parser/parser.lua:124 -"ErrGoto", -- ./lib/lua-parser/parser.lua:124 -"expected a label after 'goto'" -- ./lib/lua-parser/parser.lua:124 +"ErrOParenPList", -- ./lib/lua-parser/parser.lua:124 +"expected '(' for the parameter list" -- ./lib/lua-parser/parser.lua:124 }, -- ./lib/lua-parser/parser.lua:124 { -- ./lib/lua-parser/parser.lua:125 -"ErrRetList", -- ./lib/lua-parser/parser.lua:125 -"expected an expression after ',' in the return statement" -- ./lib/lua-parser/parser.lua:125 +"ErrCParenPList", -- ./lib/lua-parser/parser.lua:125 +"expected ')' to close the parameter list" -- ./lib/lua-parser/parser.lua:125 }, -- ./lib/lua-parser/parser.lua:125 +{ -- ./lib/lua-parser/parser.lua:126 +"ErrEndFunc", -- ./lib/lua-parser/parser.lua:126 +"expected 'end' to close the function body" -- ./lib/lua-parser/parser.lua:126 +}, -- ./lib/lua-parser/parser.lua:126 { -- ./lib/lua-parser/parser.lua:127 -"ErrVarList", -- ./lib/lua-parser/parser.lua:127 -"expected a variable name after ','" -- ./lib/lua-parser/parser.lua:127 +"ErrParList", -- ./lib/lua-parser/parser.lua:127 +"expected a variable name or '...' after ','" -- ./lib/lua-parser/parser.lua:127 }, -- ./lib/lua-parser/parser.lua:127 -{ -- ./lib/lua-parser/parser.lua:128 -"ErrExprList", -- ./lib/lua-parser/parser.lua:128 -"expected an expression after ','" -- ./lib/lua-parser/parser.lua:128 -}, -- ./lib/lua-parser/parser.lua:128 +{ -- ./lib/lua-parser/parser.lua:129 +"ErrLabel", -- ./lib/lua-parser/parser.lua:129 +"expected a label name after '::'" -- ./lib/lua-parser/parser.lua:129 +}, -- ./lib/lua-parser/parser.lua:129 { -- ./lib/lua-parser/parser.lua:130 -"ErrOrExpr", -- ./lib/lua-parser/parser.lua:130 -"expected an expression after 'or'" -- ./lib/lua-parser/parser.lua:130 +"ErrCloseLabel", -- ./lib/lua-parser/parser.lua:130 +"expected '::' after the label" -- ./lib/lua-parser/parser.lua:130 }, -- ./lib/lua-parser/parser.lua:130 { -- ./lib/lua-parser/parser.lua:131 -"ErrAndExpr", -- ./lib/lua-parser/parser.lua:131 -"expected an expression after 'and'" -- ./lib/lua-parser/parser.lua:131 +"ErrGoto", -- ./lib/lua-parser/parser.lua:131 +"expected a label after 'goto'" -- ./lib/lua-parser/parser.lua:131 }, -- ./lib/lua-parser/parser.lua:131 { -- ./lib/lua-parser/parser.lua:132 -"ErrRelExpr", -- ./lib/lua-parser/parser.lua:132 -"expected an expression after the relational operator" -- ./lib/lua-parser/parser.lua:132 +"ErrRetList", -- ./lib/lua-parser/parser.lua:132 +"expected an expression after ',' in the return statement" -- ./lib/lua-parser/parser.lua:132 }, -- ./lib/lua-parser/parser.lua:132 -{ -- ./lib/lua-parser/parser.lua:133 -"ErrBOrExpr", -- ./lib/lua-parser/parser.lua:133 -"expected an expression after '|'" -- ./lib/lua-parser/parser.lua:133 -}, -- ./lib/lua-parser/parser.lua:133 { -- ./lib/lua-parser/parser.lua:134 -"ErrBXorExpr", -- ./lib/lua-parser/parser.lua:134 -"expected an expression after '~'" -- ./lib/lua-parser/parser.lua:134 +"ErrVarList", -- ./lib/lua-parser/parser.lua:134 +"expected a variable name after ','" -- ./lib/lua-parser/parser.lua:134 }, -- ./lib/lua-parser/parser.lua:134 { -- ./lib/lua-parser/parser.lua:135 -"ErrBAndExpr", -- ./lib/lua-parser/parser.lua:135 -"expected an expression after '&'" -- ./lib/lua-parser/parser.lua:135 +"ErrExprList", -- ./lib/lua-parser/parser.lua:135 +"expected an expression after ','" -- ./lib/lua-parser/parser.lua:135 }, -- ./lib/lua-parser/parser.lua:135 -{ -- ./lib/lua-parser/parser.lua:136 -"ErrShiftExpr", -- ./lib/lua-parser/parser.lua:136 -"expected an expression after the bit shift" -- ./lib/lua-parser/parser.lua:136 -}, -- ./lib/lua-parser/parser.lua:136 { -- ./lib/lua-parser/parser.lua:137 -"ErrConcatExpr", -- ./lib/lua-parser/parser.lua:137 -"expected an expression after '..'" -- ./lib/lua-parser/parser.lua:137 +"ErrOrExpr", -- ./lib/lua-parser/parser.lua:137 +"expected an expression after 'or'" -- ./lib/lua-parser/parser.lua:137 }, -- ./lib/lua-parser/parser.lua:137 { -- ./lib/lua-parser/parser.lua:138 -"ErrAddExpr", -- ./lib/lua-parser/parser.lua:138 -"expected an expression after the additive operator" -- ./lib/lua-parser/parser.lua:138 +"ErrAndExpr", -- ./lib/lua-parser/parser.lua:138 +"expected an expression after 'and'" -- ./lib/lua-parser/parser.lua:138 }, -- ./lib/lua-parser/parser.lua:138 { -- ./lib/lua-parser/parser.lua:139 -"ErrMulExpr", -- ./lib/lua-parser/parser.lua:139 -"expected an expression after the multiplicative operator" -- ./lib/lua-parser/parser.lua:139 +"ErrRelExpr", -- ./lib/lua-parser/parser.lua:139 +"expected an expression after the relational operator" -- ./lib/lua-parser/parser.lua:139 }, -- ./lib/lua-parser/parser.lua:139 { -- ./lib/lua-parser/parser.lua:140 -"ErrUnaryExpr", -- ./lib/lua-parser/parser.lua:140 -"expected an expression after the unary operator" -- ./lib/lua-parser/parser.lua:140 +"ErrBOrExpr", -- ./lib/lua-parser/parser.lua:140 +"expected an expression after '|'" -- ./lib/lua-parser/parser.lua:140 }, -- ./lib/lua-parser/parser.lua:140 { -- ./lib/lua-parser/parser.lua:141 -"ErrPowExpr", -- ./lib/lua-parser/parser.lua:141 -"expected an expression after '^'" -- ./lib/lua-parser/parser.lua:141 +"ErrBXorExpr", -- ./lib/lua-parser/parser.lua:141 +"expected an expression after '~'" -- ./lib/lua-parser/parser.lua:141 }, -- ./lib/lua-parser/parser.lua:141 +{ -- ./lib/lua-parser/parser.lua:142 +"ErrBAndExpr", -- ./lib/lua-parser/parser.lua:142 +"expected an expression after '&'" -- ./lib/lua-parser/parser.lua:142 +}, -- ./lib/lua-parser/parser.lua:142 { -- ./lib/lua-parser/parser.lua:143 -"ErrExprParen", -- ./lib/lua-parser/parser.lua:143 -"expected an expression after '('" -- ./lib/lua-parser/parser.lua:143 +"ErrShiftExpr", -- ./lib/lua-parser/parser.lua:143 +"expected an expression after the bit shift" -- ./lib/lua-parser/parser.lua:143 }, -- ./lib/lua-parser/parser.lua:143 { -- ./lib/lua-parser/parser.lua:144 -"ErrCParenExpr", -- ./lib/lua-parser/parser.lua:144 -"expected ')' to close the expression" -- ./lib/lua-parser/parser.lua:144 +"ErrConcatExpr", -- ./lib/lua-parser/parser.lua:144 +"expected an expression after '..'" -- ./lib/lua-parser/parser.lua:144 }, -- ./lib/lua-parser/parser.lua:144 { -- ./lib/lua-parser/parser.lua:145 -"ErrNameIndex", -- ./lib/lua-parser/parser.lua:145 -"expected a field name after '.'" -- ./lib/lua-parser/parser.lua:145 +"ErrAddExpr", -- ./lib/lua-parser/parser.lua:145 +"expected an expression after the additive operator" -- ./lib/lua-parser/parser.lua:145 }, -- ./lib/lua-parser/parser.lua:145 { -- ./lib/lua-parser/parser.lua:146 -"ErrExprIndex", -- ./lib/lua-parser/parser.lua:146 -"expected an expression after '['" -- ./lib/lua-parser/parser.lua:146 +"ErrMulExpr", -- ./lib/lua-parser/parser.lua:146 +"expected an expression after the multiplicative operator" -- ./lib/lua-parser/parser.lua:146 }, -- ./lib/lua-parser/parser.lua:146 { -- ./lib/lua-parser/parser.lua:147 -"ErrCBracketIndex", -- ./lib/lua-parser/parser.lua:147 -"expected ']' to close the indexing expression" -- ./lib/lua-parser/parser.lua:147 +"ErrUnaryExpr", -- ./lib/lua-parser/parser.lua:147 +"expected an expression after the unary operator" -- ./lib/lua-parser/parser.lua:147 }, -- ./lib/lua-parser/parser.lua:147 { -- ./lib/lua-parser/parser.lua:148 -"ErrNameMeth", -- ./lib/lua-parser/parser.lua:148 -"expected a method name after ':'" -- ./lib/lua-parser/parser.lua:148 +"ErrPowExpr", -- ./lib/lua-parser/parser.lua:148 +"expected an expression after '^'" -- ./lib/lua-parser/parser.lua:148 }, -- ./lib/lua-parser/parser.lua:148 -{ -- ./lib/lua-parser/parser.lua:149 -"ErrMethArgs", -- ./lib/lua-parser/parser.lua:149 -"expected some arguments for the method call (or '()')" -- ./lib/lua-parser/parser.lua:149 -}, -- ./lib/lua-parser/parser.lua:149 +{ -- ./lib/lua-parser/parser.lua:150 +"ErrExprParen", -- ./lib/lua-parser/parser.lua:150 +"expected an expression after '('" -- ./lib/lua-parser/parser.lua:150 +}, -- ./lib/lua-parser/parser.lua:150 { -- ./lib/lua-parser/parser.lua:151 -"ErrArgList", -- ./lib/lua-parser/parser.lua:151 -"expected an expression after ',' in the argument list" -- ./lib/lua-parser/parser.lua:151 +"ErrCParenExpr", -- ./lib/lua-parser/parser.lua:151 +"expected ')' to close the expression" -- ./lib/lua-parser/parser.lua:151 }, -- ./lib/lua-parser/parser.lua:151 { -- ./lib/lua-parser/parser.lua:152 -"ErrCParenArgs", -- ./lib/lua-parser/parser.lua:152 -"expected ')' to close the argument list" -- ./lib/lua-parser/parser.lua:152 +"ErrNameIndex", -- ./lib/lua-parser/parser.lua:152 +"expected a field name after '.'" -- ./lib/lua-parser/parser.lua:152 }, -- ./lib/lua-parser/parser.lua:152 +{ -- ./lib/lua-parser/parser.lua:153 +"ErrExprIndex", -- ./lib/lua-parser/parser.lua:153 +"expected an expression after '['" -- ./lib/lua-parser/parser.lua:153 +}, -- ./lib/lua-parser/parser.lua:153 { -- ./lib/lua-parser/parser.lua:154 -"ErrCBraceTable", -- ./lib/lua-parser/parser.lua:154 -"expected '}' to close the table constructor" -- ./lib/lua-parser/parser.lua:154 +"ErrCBracketIndex", -- ./lib/lua-parser/parser.lua:154 +"expected ']' to close the indexing expression" -- ./lib/lua-parser/parser.lua:154 }, -- ./lib/lua-parser/parser.lua:154 { -- ./lib/lua-parser/parser.lua:155 -"ErrEqField", -- ./lib/lua-parser/parser.lua:155 -"expected '=' after the table key" -- ./lib/lua-parser/parser.lua:155 +"ErrNameMeth", -- ./lib/lua-parser/parser.lua:155 +"expected a method name after ':'" -- ./lib/lua-parser/parser.lua:155 }, -- ./lib/lua-parser/parser.lua:155 { -- ./lib/lua-parser/parser.lua:156 -"ErrExprField", -- ./lib/lua-parser/parser.lua:156 -"expected an expression after '='" -- ./lib/lua-parser/parser.lua:156 +"ErrMethArgs", -- ./lib/lua-parser/parser.lua:156 +"expected some arguments for the method call (or '()')" -- ./lib/lua-parser/parser.lua:156 }, -- ./lib/lua-parser/parser.lua:156 -{ -- ./lib/lua-parser/parser.lua:157 -"ErrExprFKey", -- ./lib/lua-parser/parser.lua:157 -"expected an expression after '[' for the table key" -- ./lib/lua-parser/parser.lua:157 -}, -- ./lib/lua-parser/parser.lua:157 { -- ./lib/lua-parser/parser.lua:158 -"ErrCBracketFKey", -- ./lib/lua-parser/parser.lua:158 -"expected ']' to close the table key" -- ./lib/lua-parser/parser.lua:158 +"ErrArgList", -- ./lib/lua-parser/parser.lua:158 +"expected an expression after ',' in the argument list" -- ./lib/lua-parser/parser.lua:158 }, -- ./lib/lua-parser/parser.lua:158 -{ -- ./lib/lua-parser/parser.lua:160 -"ErrCBracketTableCompr", -- ./lib/lua-parser/parser.lua:160 -"expected ']' to close the table comprehension" -- ./lib/lua-parser/parser.lua:160 -}, -- ./lib/lua-parser/parser.lua:160 +{ -- ./lib/lua-parser/parser.lua:159 +"ErrCParenArgs", -- ./lib/lua-parser/parser.lua:159 +"expected ')' to close the argument list" -- ./lib/lua-parser/parser.lua:159 +}, -- ./lib/lua-parser/parser.lua:159 +{ -- ./lib/lua-parser/parser.lua:161 +"ErrCBraceTable", -- ./lib/lua-parser/parser.lua:161 +"expected '}' to close the table constructor" -- ./lib/lua-parser/parser.lua:161 +}, -- ./lib/lua-parser/parser.lua:161 { -- ./lib/lua-parser/parser.lua:162 -"ErrDigitHex", -- ./lib/lua-parser/parser.lua:162 -"expected one or more hexadecimal digits after '0x'" -- ./lib/lua-parser/parser.lua:162 +"ErrEqField", -- ./lib/lua-parser/parser.lua:162 +"expected '=' after the table key" -- ./lib/lua-parser/parser.lua:162 }, -- ./lib/lua-parser/parser.lua:162 { -- ./lib/lua-parser/parser.lua:163 -"ErrDigitDeci", -- ./lib/lua-parser/parser.lua:163 -"expected one or more digits after the decimal point" -- ./lib/lua-parser/parser.lua:163 +"ErrExprField", -- ./lib/lua-parser/parser.lua:163 +"expected an expression after '='" -- ./lib/lua-parser/parser.lua:163 }, -- ./lib/lua-parser/parser.lua:163 { -- ./lib/lua-parser/parser.lua:164 -"ErrDigitExpo", -- ./lib/lua-parser/parser.lua:164 -"expected one or more digits for the exponent" -- ./lib/lua-parser/parser.lua:164 +"ErrExprFKey", -- ./lib/lua-parser/parser.lua:164 +"expected an expression after '[' for the table key" -- ./lib/lua-parser/parser.lua:164 }, -- ./lib/lua-parser/parser.lua:164 -{ -- ./lib/lua-parser/parser.lua:166 -"ErrQuote", -- ./lib/lua-parser/parser.lua:166 -"unclosed string" -- ./lib/lua-parser/parser.lua:166 -}, -- ./lib/lua-parser/parser.lua:166 +{ -- ./lib/lua-parser/parser.lua:165 +"ErrCBracketFKey", -- ./lib/lua-parser/parser.lua:165 +"expected ']' to close the table key" -- ./lib/lua-parser/parser.lua:165 +}, -- ./lib/lua-parser/parser.lua:165 { -- ./lib/lua-parser/parser.lua:167 -"ErrHexEsc", -- ./lib/lua-parser/parser.lua:167 -"expected exactly two hexadecimal digits after '\\x'" -- ./lib/lua-parser/parser.lua:167 +"ErrCBracketTableCompr", -- ./lib/lua-parser/parser.lua:167 +"expected ']' to close the table comprehension" -- ./lib/lua-parser/parser.lua:167 }, -- ./lib/lua-parser/parser.lua:167 -{ -- ./lib/lua-parser/parser.lua:168 -"ErrOBraceUEsc", -- ./lib/lua-parser/parser.lua:168 -"expected '{' after '\\u'" -- ./lib/lua-parser/parser.lua:168 -}, -- ./lib/lua-parser/parser.lua:168 { -- ./lib/lua-parser/parser.lua:169 -"ErrDigitUEsc", -- ./lib/lua-parser/parser.lua:169 -"expected one or more hexadecimal digits for the UTF-8 code point" -- ./lib/lua-parser/parser.lua:169 +"ErrDigitHex", -- ./lib/lua-parser/parser.lua:169 +"expected one or more hexadecimal digits after '0x'" -- ./lib/lua-parser/parser.lua:169 }, -- ./lib/lua-parser/parser.lua:169 { -- ./lib/lua-parser/parser.lua:170 -"ErrCBraceUEsc", -- ./lib/lua-parser/parser.lua:170 -"expected '}' after the code point" -- ./lib/lua-parser/parser.lua:170 +"ErrDigitDeci", -- ./lib/lua-parser/parser.lua:170 +"expected one or more digits after the decimal point" -- ./lib/lua-parser/parser.lua:170 }, -- ./lib/lua-parser/parser.lua:170 { -- ./lib/lua-parser/parser.lua:171 -"ErrEscSeq", -- ./lib/lua-parser/parser.lua:171 -"invalid escape sequence" -- ./lib/lua-parser/parser.lua:171 +"ErrDigitExpo", -- ./lib/lua-parser/parser.lua:171 +"expected one or more digits for the exponent" -- ./lib/lua-parser/parser.lua:171 }, -- ./lib/lua-parser/parser.lua:171 -{ -- ./lib/lua-parser/parser.lua:172 -"ErrCloseLStr", -- ./lib/lua-parser/parser.lua:172 -"unclosed long string" -- ./lib/lua-parser/parser.lua:172 -} -- ./lib/lua-parser/parser.lua:172 -} -- ./lib/lua-parser/parser.lua:172 -local function throw(label) -- ./lib/lua-parser/parser.lua:175 -label = "Err" .. label -- ./lib/lua-parser/parser.lua:176 -for i, labelinfo in ipairs(labels) do -- ./lib/lua-parser/parser.lua:177 -if labelinfo[1] == label then -- ./lib/lua-parser/parser.lua:178 -return T(i) -- ./lib/lua-parser/parser.lua:179 -end -- ./lib/lua-parser/parser.lua:179 -end -- ./lib/lua-parser/parser.lua:179 -error("Label not found: " .. label) -- ./lib/lua-parser/parser.lua:183 -end -- ./lib/lua-parser/parser.lua:183 -local function expect(patt, label) -- ./lib/lua-parser/parser.lua:186 -return patt + throw(label) -- ./lib/lua-parser/parser.lua:187 -end -- ./lib/lua-parser/parser.lua:187 -local function token(patt) -- ./lib/lua-parser/parser.lua:193 -return patt * V("Skip") -- ./lib/lua-parser/parser.lua:194 +{ -- ./lib/lua-parser/parser.lua:173 +"ErrQuote", -- ./lib/lua-parser/parser.lua:173 +"unclosed string" -- ./lib/lua-parser/parser.lua:173 +}, -- ./lib/lua-parser/parser.lua:173 +{ -- ./lib/lua-parser/parser.lua:174 +"ErrHexEsc", -- ./lib/lua-parser/parser.lua:174 +"expected exactly two hexadecimal digits after '\\x'" -- ./lib/lua-parser/parser.lua:174 +}, -- ./lib/lua-parser/parser.lua:174 +{ -- ./lib/lua-parser/parser.lua:175 +"ErrOBraceUEsc", -- ./lib/lua-parser/parser.lua:175 +"expected '{' after '\\u'" -- ./lib/lua-parser/parser.lua:175 +}, -- ./lib/lua-parser/parser.lua:175 +{ -- ./lib/lua-parser/parser.lua:176 +"ErrDigitUEsc", -- ./lib/lua-parser/parser.lua:176 +"expected one or more hexadecimal digits for the UTF-8 code point" -- ./lib/lua-parser/parser.lua:176 +}, -- ./lib/lua-parser/parser.lua:176 +{ -- ./lib/lua-parser/parser.lua:177 +"ErrCBraceUEsc", -- ./lib/lua-parser/parser.lua:177 +"expected '}' after the code point" -- ./lib/lua-parser/parser.lua:177 +}, -- ./lib/lua-parser/parser.lua:177 +{ -- ./lib/lua-parser/parser.lua:178 +"ErrEscSeq", -- ./lib/lua-parser/parser.lua:178 +"invalid escape sequence" -- ./lib/lua-parser/parser.lua:178 +}, -- ./lib/lua-parser/parser.lua:178 +{ -- ./lib/lua-parser/parser.lua:179 +"ErrCloseLStr", -- ./lib/lua-parser/parser.lua:179 +"unclosed long string" -- ./lib/lua-parser/parser.lua:179 +} -- ./lib/lua-parser/parser.lua:179 +} -- ./lib/lua-parser/parser.lua:179 +local function throw(label) -- ./lib/lua-parser/parser.lua:182 +label = "Err" .. label -- ./lib/lua-parser/parser.lua:183 +for i, labelinfo in ipairs(labels) do -- ./lib/lua-parser/parser.lua:184 +if labelinfo[1] == label then -- ./lib/lua-parser/parser.lua:185 +return T(i) -- ./lib/lua-parser/parser.lua:186 +end -- ./lib/lua-parser/parser.lua:186 +end -- ./lib/lua-parser/parser.lua:186 +error("Label not found: " .. label) -- ./lib/lua-parser/parser.lua:190 +end -- ./lib/lua-parser/parser.lua:190 +local function expect(patt, label) -- ./lib/lua-parser/parser.lua:193 +return patt + throw(label) -- ./lib/lua-parser/parser.lua:194 end -- ./lib/lua-parser/parser.lua:194 -local function sym(str) -- ./lib/lua-parser/parser.lua:197 -return token(P(str)) -- ./lib/lua-parser/parser.lua:198 -end -- ./lib/lua-parser/parser.lua:198 -local function kw(str) -- ./lib/lua-parser/parser.lua:201 -return token(P(str) * - V("IdRest")) -- ./lib/lua-parser/parser.lua:202 -end -- ./lib/lua-parser/parser.lua:202 -local function tagC(tag, patt) -- ./lib/lua-parser/parser.lua:205 -return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./lib/lua-parser/parser.lua:206 -end -- ./lib/lua-parser/parser.lua:206 -local function unaryOp(op, e) -- ./lib/lua-parser/parser.lua:209 -return { -- ./lib/lua-parser/parser.lua:210 -["tag"] = "Op", -- ./lib/lua-parser/parser.lua:210 -["pos"] = e["pos"], -- ./lib/lua-parser/parser.lua:210 -[1] = op, -- ./lib/lua-parser/parser.lua:210 -[2] = e -- ./lib/lua-parser/parser.lua:210 -} -- ./lib/lua-parser/parser.lua:210 -end -- ./lib/lua-parser/parser.lua:210 -local function binaryOp(e1, op, e2) -- ./lib/lua-parser/parser.lua:213 -if not op then -- ./lib/lua-parser/parser.lua:214 -return e1 -- ./lib/lua-parser/parser.lua:215 -else -- ./lib/lua-parser/parser.lua:215 +local function token(patt) -- ./lib/lua-parser/parser.lua:200 +return patt * V("Skip") -- ./lib/lua-parser/parser.lua:201 +end -- ./lib/lua-parser/parser.lua:201 +local function sym(str) -- ./lib/lua-parser/parser.lua:204 +return token(P(str)) -- ./lib/lua-parser/parser.lua:205 +end -- ./lib/lua-parser/parser.lua:205 +local function kw(str) -- ./lib/lua-parser/parser.lua:208 +return token(P(str) * - V("IdRest")) -- ./lib/lua-parser/parser.lua:209 +end -- ./lib/lua-parser/parser.lua:209 +local function tagC(tag, patt) -- ./lib/lua-parser/parser.lua:212 +return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./lib/lua-parser/parser.lua:213 +end -- ./lib/lua-parser/parser.lua:213 +local function unaryOp(op, e) -- ./lib/lua-parser/parser.lua:216 return { -- ./lib/lua-parser/parser.lua:217 ["tag"] = "Op", -- ./lib/lua-parser/parser.lua:217 -["pos"] = e1["pos"], -- ./lib/lua-parser/parser.lua:217 +["pos"] = e["pos"], -- ./lib/lua-parser/parser.lua:217 [1] = op, -- ./lib/lua-parser/parser.lua:217 -[2] = e1, -- ./lib/lua-parser/parser.lua:217 -[3] = e2 -- ./lib/lua-parser/parser.lua:217 +[2] = e -- ./lib/lua-parser/parser.lua:217 } -- ./lib/lua-parser/parser.lua:217 end -- ./lib/lua-parser/parser.lua:217 -end -- ./lib/lua-parser/parser.lua:217 -local function sepBy(patt, sep, label) -- ./lib/lua-parser/parser.lua:221 -if label then -- ./lib/lua-parser/parser.lua:222 -return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./lib/lua-parser/parser.lua:223 -else -- ./lib/lua-parser/parser.lua:223 -return patt * Cg(sep * patt) ^ 0 -- ./lib/lua-parser/parser.lua:225 -end -- ./lib/lua-parser/parser.lua:225 -end -- ./lib/lua-parser/parser.lua:225 -local function chainOp(patt, sep, label) -- ./lib/lua-parser/parser.lua:229 -return Cf(sepBy(patt, sep, label), binaryOp) -- ./lib/lua-parser/parser.lua:230 -end -- ./lib/lua-parser/parser.lua:230 -local function commaSep(patt, label) -- ./lib/lua-parser/parser.lua:233 -return sepBy(patt, sym(","), label) -- ./lib/lua-parser/parser.lua:234 -end -- ./lib/lua-parser/parser.lua:234 -local function tagDo(block) -- ./lib/lua-parser/parser.lua:237 -block["tag"] = "Do" -- ./lib/lua-parser/parser.lua:238 -return block -- ./lib/lua-parser/parser.lua:239 -end -- ./lib/lua-parser/parser.lua:239 -local function fixFuncStat(func) -- ./lib/lua-parser/parser.lua:242 -if func[1]["is_method"] then -- ./lib/lua-parser/parser.lua:243 -table["insert"](func[2][1], 1, { -- ./lib/lua-parser/parser.lua:243 -["tag"] = "Id", -- ./lib/lua-parser/parser.lua:243 -[1] = "self" -- ./lib/lua-parser/parser.lua:243 -}) -- ./lib/lua-parser/parser.lua:243 -end -- ./lib/lua-parser/parser.lua:243 -func[1] = { func[1] } -- ./lib/lua-parser/parser.lua:244 -func[2] = { func[2] } -- ./lib/lua-parser/parser.lua:245 -return func -- ./lib/lua-parser/parser.lua:246 +local function binaryOp(e1, op, e2) -- ./lib/lua-parser/parser.lua:220 +if not op then -- ./lib/lua-parser/parser.lua:221 +return e1 -- ./lib/lua-parser/parser.lua:222 +else -- ./lib/lua-parser/parser.lua:222 +return { -- ./lib/lua-parser/parser.lua:224 +["tag"] = "Op", -- ./lib/lua-parser/parser.lua:224 +["pos"] = e1["pos"], -- ./lib/lua-parser/parser.lua:224 +[1] = op, -- ./lib/lua-parser/parser.lua:224 +[2] = e1, -- ./lib/lua-parser/parser.lua:224 +[3] = e2 -- ./lib/lua-parser/parser.lua:224 +} -- ./lib/lua-parser/parser.lua:224 +end -- ./lib/lua-parser/parser.lua:224 +end -- ./lib/lua-parser/parser.lua:224 +local function sepBy(patt, sep, label) -- ./lib/lua-parser/parser.lua:228 +if label then -- ./lib/lua-parser/parser.lua:229 +return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./lib/lua-parser/parser.lua:230 +else -- ./lib/lua-parser/parser.lua:230 +return patt * Cg(sep * patt) ^ 0 -- ./lib/lua-parser/parser.lua:232 +end -- ./lib/lua-parser/parser.lua:232 +end -- ./lib/lua-parser/parser.lua:232 +local function chainOp(patt, sep, label) -- ./lib/lua-parser/parser.lua:236 +return Cf(sepBy(patt, sep, label), binaryOp) -- ./lib/lua-parser/parser.lua:237 +end -- ./lib/lua-parser/parser.lua:237 +local function commaSep(patt, label) -- ./lib/lua-parser/parser.lua:240 +return sepBy(patt, sym(","), label) -- ./lib/lua-parser/parser.lua:241 +end -- ./lib/lua-parser/parser.lua:241 +local function tagDo(block) -- ./lib/lua-parser/parser.lua:244 +block["tag"] = "Do" -- ./lib/lua-parser/parser.lua:245 +return block -- ./lib/lua-parser/parser.lua:246 end -- ./lib/lua-parser/parser.lua:246 -local function addDots(params, dots) -- ./lib/lua-parser/parser.lua:249 -if dots then -- ./lib/lua-parser/parser.lua:250 -table["insert"](params, dots) -- ./lib/lua-parser/parser.lua:250 +local function fixFuncStat(func) -- ./lib/lua-parser/parser.lua:249 +if func[1]["is_method"] then -- ./lib/lua-parser/parser.lua:250 +table["insert"](func[2][1], 1, { -- ./lib/lua-parser/parser.lua:250 +["tag"] = "Id", -- ./lib/lua-parser/parser.lua:250 +[1] = "self" -- ./lib/lua-parser/parser.lua:250 +}) -- ./lib/lua-parser/parser.lua:250 end -- ./lib/lua-parser/parser.lua:250 -return params -- ./lib/lua-parser/parser.lua:251 -end -- ./lib/lua-parser/parser.lua:251 -local function insertIndex(t, index) -- ./lib/lua-parser/parser.lua:254 -return { -- ./lib/lua-parser/parser.lua:255 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:255 -["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:255 -[1] = t, -- ./lib/lua-parser/parser.lua:255 -[2] = index -- ./lib/lua-parser/parser.lua:255 -} -- ./lib/lua-parser/parser.lua:255 -end -- ./lib/lua-parser/parser.lua:255 -local function markMethod(t, method) -- ./lib/lua-parser/parser.lua:258 -if method then -- ./lib/lua-parser/parser.lua:259 -return { -- ./lib/lua-parser/parser.lua:260 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:260 -["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:260 -["is_method"] = true, -- ./lib/lua-parser/parser.lua:260 -[1] = t, -- ./lib/lua-parser/parser.lua:260 -[2] = method -- ./lib/lua-parser/parser.lua:260 -} -- ./lib/lua-parser/parser.lua:260 -end -- ./lib/lua-parser/parser.lua:260 -return t -- ./lib/lua-parser/parser.lua:262 +func[1] = { func[1] } -- ./lib/lua-parser/parser.lua:251 +func[2] = { func[2] } -- ./lib/lua-parser/parser.lua:252 +return func -- ./lib/lua-parser/parser.lua:253 +end -- ./lib/lua-parser/parser.lua:253 +local function addDots(params, dots) -- ./lib/lua-parser/parser.lua:256 +if dots then -- ./lib/lua-parser/parser.lua:257 +table["insert"](params, dots) -- ./lib/lua-parser/parser.lua:257 +end -- ./lib/lua-parser/parser.lua:257 +return params -- ./lib/lua-parser/parser.lua:258 +end -- ./lib/lua-parser/parser.lua:258 +local function insertIndex(t, index) -- ./lib/lua-parser/parser.lua:261 +return { -- ./lib/lua-parser/parser.lua:262 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:262 +["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:262 +[1] = t, -- ./lib/lua-parser/parser.lua:262 +[2] = index -- ./lib/lua-parser/parser.lua:262 +} -- ./lib/lua-parser/parser.lua:262 end -- ./lib/lua-parser/parser.lua:262 -local function makeIndexOrCall(t1, t2) -- ./lib/lua-parser/parser.lua:265 -if t2["tag"] == "Call" or t2["tag"] == "Invoke" then -- ./lib/lua-parser/parser.lua:266 -local t = { -- ./lib/lua-parser/parser.lua:267 -["tag"] = t2["tag"], -- ./lib/lua-parser/parser.lua:267 -["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:267 -[1] = t1 -- ./lib/lua-parser/parser.lua:267 +local function markMethod(t, method) -- ./lib/lua-parser/parser.lua:265 +if method then -- ./lib/lua-parser/parser.lua:266 +return { -- ./lib/lua-parser/parser.lua:267 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:267 +["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:267 +["is_method"] = true, -- ./lib/lua-parser/parser.lua:267 +[1] = t, -- ./lib/lua-parser/parser.lua:267 +[2] = method -- ./lib/lua-parser/parser.lua:267 } -- ./lib/lua-parser/parser.lua:267 -for k, v in ipairs(t2) do -- ./lib/lua-parser/parser.lua:268 -table["insert"](t, v) -- ./lib/lua-parser/parser.lua:269 +end -- ./lib/lua-parser/parser.lua:267 +return t -- ./lib/lua-parser/parser.lua:269 end -- ./lib/lua-parser/parser.lua:269 -return t -- ./lib/lua-parser/parser.lua:271 -end -- ./lib/lua-parser/parser.lua:271 -return { -- ./lib/lua-parser/parser.lua:273 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:273 -["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:273 -[1] = t1, -- ./lib/lua-parser/parser.lua:273 -[2] = t2[1] -- ./lib/lua-parser/parser.lua:273 -} -- ./lib/lua-parser/parser.lua:273 -end -- ./lib/lua-parser/parser.lua:273 -local function fixShortFunc(t) -- ./lib/lua-parser/parser.lua:276 -if t[1] == ":" then -- self method -- ./lib/lua-parser/parser.lua:277 -table["insert"](t[2], 1, { -- ./lib/lua-parser/parser.lua:278 -["tag"] = "Id", -- ./lib/lua-parser/parser.lua:278 -"self" -- ./lib/lua-parser/parser.lua:278 -}) -- ./lib/lua-parser/parser.lua:278 -table["remove"](t, 1) -- ./lib/lua-parser/parser.lua:279 -t["is_method"] = true -- ./lib/lua-parser/parser.lua:280 -end -- ./lib/lua-parser/parser.lua:280 -t["is_short"] = true -- ./lib/lua-parser/parser.lua:282 -return t -- ./lib/lua-parser/parser.lua:283 -end -- ./lib/lua-parser/parser.lua:283 -local function statToExpr(t) -- tag a StatExpr -- ./lib/lua-parser/parser.lua:286 -t["tag"] = t["tag"] .. "Expr" -- ./lib/lua-parser/parser.lua:287 -return t -- ./lib/lua-parser/parser.lua:288 -end -- ./lib/lua-parser/parser.lua:288 -local function fixStructure(t) -- fix the AST structure if needed -- ./lib/lua-parser/parser.lua:291 -local i = 1 -- ./lib/lua-parser/parser.lua:292 -while i <= # t do -- ./lib/lua-parser/parser.lua:293 -if type(t[i]) == "table" then -- ./lib/lua-parser/parser.lua:294 -fixStructure(t[i]) -- ./lib/lua-parser/parser.lua:295 -for j = # t[i], 1, - 1 do -- ./lib/lua-parser/parser.lua:296 -local stat = t[i][j] -- ./lib/lua-parser/parser.lua:297 -if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./lib/lua-parser/parser.lua:298 -table["remove"](t[i], j) -- ./lib/lua-parser/parser.lua:299 -table["insert"](t, i + 1, stat) -- ./lib/lua-parser/parser.lua:300 -if t["tag"] == "Block" or t["tag"] == "Do" then -- ./lib/lua-parser/parser.lua:301 -stat["move_up_block"] = stat["move_up_block"] - 1 -- ./lib/lua-parser/parser.lua:302 +local function makeSuffixedExpr(t1, t2) -- ./lib/lua-parser/parser.lua:272 +if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./lib/lua-parser/parser.lua:273 +local t = { -- ./lib/lua-parser/parser.lua:274 +["tag"] = t2["tag"], -- ./lib/lua-parser/parser.lua:274 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:274 +[1] = t1 -- ./lib/lua-parser/parser.lua:274 +} -- ./lib/lua-parser/parser.lua:274 +for k, v in ipairs(t2) do -- ./lib/lua-parser/parser.lua:275 +table["insert"](t, v) -- ./lib/lua-parser/parser.lua:276 +end -- ./lib/lua-parser/parser.lua:276 +return t -- ./lib/lua-parser/parser.lua:278 +elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./lib/lua-parser/parser.lua:279 +return { -- ./lib/lua-parser/parser.lua:280 +["tag"] = t2["tag"], -- ./lib/lua-parser/parser.lua:280 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:280 +[1] = t1, -- ./lib/lua-parser/parser.lua:280 +[2] = t2[1] -- ./lib/lua-parser/parser.lua:280 +} -- ./lib/lua-parser/parser.lua:280 +elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./lib/lua-parser/parser.lua:281 +return { -- ./lib/lua-parser/parser.lua:282 +["tag"] = "SafeIndex", -- ./lib/lua-parser/parser.lua:282 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:282 +[1] = t1, -- ./lib/lua-parser/parser.lua:282 +[2] = t2[1] -- ./lib/lua-parser/parser.lua:282 +} -- ./lib/lua-parser/parser.lua:282 +elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./lib/lua-parser/parser.lua:283 +return { -- ./lib/lua-parser/parser.lua:284 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:284 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:284 +[1] = t1, -- ./lib/lua-parser/parser.lua:284 +[2] = t2[1] -- ./lib/lua-parser/parser.lua:284 +} -- ./lib/lua-parser/parser.lua:284 +else -- ./lib/lua-parser/parser.lua:284 +error("unexpected tag in suffixed expression") -- ./lib/lua-parser/parser.lua:286 +end -- ./lib/lua-parser/parser.lua:286 +end -- ./lib/lua-parser/parser.lua:286 +local function fixShortFunc(t) -- ./lib/lua-parser/parser.lua:290 +if t[1] == ":" then -- self method -- ./lib/lua-parser/parser.lua:291 +table["insert"](t[2], 1, { -- ./lib/lua-parser/parser.lua:292 +["tag"] = "Id", -- ./lib/lua-parser/parser.lua:292 +"self" -- ./lib/lua-parser/parser.lua:292 +}) -- ./lib/lua-parser/parser.lua:292 +table["remove"](t, 1) -- ./lib/lua-parser/parser.lua:293 +t["is_method"] = true -- ./lib/lua-parser/parser.lua:294 +end -- ./lib/lua-parser/parser.lua:294 +t["is_short"] = true -- ./lib/lua-parser/parser.lua:296 +return t -- ./lib/lua-parser/parser.lua:297 +end -- ./lib/lua-parser/parser.lua:297 +local function statToExpr(t) -- tag a StatExpr -- ./lib/lua-parser/parser.lua:300 +t["tag"] = t["tag"] .. "Expr" -- ./lib/lua-parser/parser.lua:301 +return t -- ./lib/lua-parser/parser.lua:302 end -- ./lib/lua-parser/parser.lua:302 -end -- ./lib/lua-parser/parser.lua:302 -end -- ./lib/lua-parser/parser.lua:302 -end -- ./lib/lua-parser/parser.lua:302 -i = i + 1 -- ./lib/lua-parser/parser.lua:307 -end -- ./lib/lua-parser/parser.lua:307 -return t -- ./lib/lua-parser/parser.lua:309 -end -- ./lib/lua-parser/parser.lua:309 -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) -- ./lib/lua-parser/parser.lua:312 -for i, stat in ipairs(block) do -- ./lib/lua-parser/parser.lua:313 -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 -- ./lib/lua-parser/parser.lua:315 -local exprlist -- ./lib/lua-parser/parser.lua:316 -if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./lib/lua-parser/parser.lua:318 -exprlist = stat[# stat] -- ./lib/lua-parser/parser.lua:319 -elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./lib/lua-parser/parser.lua:320 -exprlist = stat -- ./lib/lua-parser/parser.lua:321 +local function fixStructure(t) -- fix the AST structure if needed -- ./lib/lua-parser/parser.lua:305 +local i = 1 -- ./lib/lua-parser/parser.lua:306 +while i <= # t do -- ./lib/lua-parser/parser.lua:307 +if type(t[i]) == "table" then -- ./lib/lua-parser/parser.lua:308 +fixStructure(t[i]) -- ./lib/lua-parser/parser.lua:309 +for j = # t[i], 1, - 1 do -- ./lib/lua-parser/parser.lua:310 +local stat = t[i][j] -- ./lib/lua-parser/parser.lua:311 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./lib/lua-parser/parser.lua:312 +table["remove"](t[i], j) -- ./lib/lua-parser/parser.lua:313 +table["insert"](t, i + 1, stat) -- ./lib/lua-parser/parser.lua:314 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./lib/lua-parser/parser.lua:315 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./lib/lua-parser/parser.lua:316 +end -- ./lib/lua-parser/parser.lua:316 +end -- ./lib/lua-parser/parser.lua:316 +end -- ./lib/lua-parser/parser.lua:316 +end -- ./lib/lua-parser/parser.lua:316 +i = i + 1 -- ./lib/lua-parser/parser.lua:321 end -- ./lib/lua-parser/parser.lua:321 -local last = exprlist[# exprlist] -- last value in ExprList -- ./lib/lua-parser/parser.lua:324 -if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./lib/lua-parser/parser.lua:328 -local p = i -- ./lib/lua-parser/parser.lua:329 -for j, fstat in ipairs(last[2]) do -- ./lib/lua-parser/parser.lua:330 -p = i + j -- ./lib/lua-parser/parser.lua:331 -table["insert"](block, p, fstat) -- copy stats from func body to block -- ./lib/lua-parser/parser.lua:332 -if stat["move_up_block"] then -- extracted stats inherit move_up_block from statement -- ./lib/lua-parser/parser.lua:334 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./lib/lua-parser/parser.lua:335 +return t -- ./lib/lua-parser/parser.lua:323 +end -- ./lib/lua-parser/parser.lua:323 +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) -- ./lib/lua-parser/parser.lua:326 +for i, stat in ipairs(block) do -- ./lib/lua-parser/parser.lua:327 +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 -- ./lib/lua-parser/parser.lua:329 +local exprlist -- ./lib/lua-parser/parser.lua:330 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./lib/lua-parser/parser.lua:332 +exprlist = stat[# stat] -- ./lib/lua-parser/parser.lua:333 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./lib/lua-parser/parser.lua:334 +exprlist = stat -- ./lib/lua-parser/parser.lua:335 end -- ./lib/lua-parser/parser.lua:335 -if block["is_singlestatblock"] then -- if it's a single stat block, mark them to move them outside of the block -- ./lib/lua-parser/parser.lua:338 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:339 -end -- ./lib/lua-parser/parser.lua:339 -end -- ./lib/lua-parser/parser.lua:339 -exprlist[# exprlist] = last[1] -- replace func with paren and expressions -- ./lib/lua-parser/parser.lua:343 -exprlist[# exprlist]["tag"] = "Paren" -- ./lib/lua-parser/parser.lua:344 -if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:346 -for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:347 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:348 -end -- ./lib/lua-parser/parser.lua:348 -end -- ./lib/lua-parser/parser.lua:348 -return block, i -- ./lib/lua-parser/parser.lua:352 -elseif last["tag"]:match("Expr$") then -- ./lib/lua-parser/parser.lua:355 -local r = searchEndRec({ last }) -- ./lib/lua-parser/parser.lua:356 -if r then -- ./lib/lua-parser/parser.lua:357 -for j = 2, # r, 1 do -- ./lib/lua-parser/parser.lua:358 -table["insert"](block, i + j - 1, r[j]) -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:359 -end -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:359 -return block, i -- ./lib/lua-parser/parser.lua:361 -end -- ./lib/lua-parser/parser.lua:361 -elseif last["tag"] == "Function" then -- ./lib/lua-parser/parser.lua:363 -local r = searchEndRec(last[2]) -- ./lib/lua-parser/parser.lua:364 -if r then -- ./lib/lua-parser/parser.lua:365 +local last = exprlist[# exprlist] -- last value in ExprList -- ./lib/lua-parser/parser.lua:338 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./lib/lua-parser/parser.lua:342 +local p = i -- ./lib/lua-parser/parser.lua:343 +for j, fstat in ipairs(last[2]) do -- ./lib/lua-parser/parser.lua:344 +p = i + j -- ./lib/lua-parser/parser.lua:345 +table["insert"](block, p, fstat) -- copy stats from func body to block -- ./lib/lua-parser/parser.lua:346 +if stat["move_up_block"] then -- extracted stats inherit move_up_block from statement -- ./lib/lua-parser/parser.lua:348 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./lib/lua-parser/parser.lua:349 +end -- ./lib/lua-parser/parser.lua:349 +if block["is_singlestatblock"] then -- if it's a single stat block, mark them to move them outside of the block -- ./lib/lua-parser/parser.lua:352 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:353 +end -- ./lib/lua-parser/parser.lua:353 +end -- ./lib/lua-parser/parser.lua:353 +exprlist[# exprlist] = last[1] -- replace func with paren and expressions -- ./lib/lua-parser/parser.lua:357 +exprlist[# exprlist]["tag"] = "Paren" -- ./lib/lua-parser/parser.lua:358 +if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:360 +for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:361 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:362 +end -- ./lib/lua-parser/parser.lua:362 +end -- ./lib/lua-parser/parser.lua:362 return block, i -- ./lib/lua-parser/parser.lua:366 -end -- ./lib/lua-parser/parser.lua:366 -end -- ./lib/lua-parser/parser.lua:366 -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 -- ./lib/lua-parser/parser.lua:371 -local blocks -- ./lib/lua-parser/parser.lua:372 -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 -- ./lib/lua-parser/parser.lua:374 -blocks = stat -- ./lib/lua-parser/parser.lua:375 -elseif stat["tag"]:match("^Do") then -- ./lib/lua-parser/parser.lua:376 -blocks = { stat } -- ./lib/lua-parser/parser.lua:377 -end -- ./lib/lua-parser/parser.lua:377 -for _, iblock in ipairs(blocks) do -- ./lib/lua-parser/parser.lua:380 -if iblock["tag"] == "Block" then -- blocks -- ./lib/lua-parser/parser.lua:381 -local oldLen = # iblock -- ./lib/lua-parser/parser.lua:382 -local newiBlock, newEnd = searchEndRec(iblock, true) -- ./lib/lua-parser/parser.lua:383 -if newiBlock then -- if end in the block -- ./lib/lua-parser/parser.lua:384 -local p = i -- ./lib/lua-parser/parser.lua:385 -for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- move all statements after the newely added statements to the parent block -- ./lib/lua-parser/parser.lua:386 -p = p + 1 -- ./lib/lua-parser/parser.lua:387 -table["insert"](block, p, iblock[j]) -- ./lib/lua-parser/parser.lua:388 -iblock[j] = nil -- ./lib/lua-parser/parser.lua:389 -end -- ./lib/lua-parser/parser.lua:389 -if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:392 -for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:393 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:394 -end -- ./lib/lua-parser/parser.lua:394 -end -- ./lib/lua-parser/parser.lua:394 -return block, i -- ./lib/lua-parser/parser.lua:398 -end -- ./lib/lua-parser/parser.lua:398 -end -- ./lib/lua-parser/parser.lua:398 -end -- ./lib/lua-parser/parser.lua:398 -end -- ./lib/lua-parser/parser.lua:398 -end -- ./lib/lua-parser/parser.lua:398 -return nil -- ./lib/lua-parser/parser.lua:404 -end -- ./lib/lua-parser/parser.lua:404 -local function searchEnd(s, p, t) -- match time capture which try to restructure the AST to free an "end" for us -- ./lib/lua-parser/parser.lua:407 -local r = searchEndRec(fixStructure(t)) -- ./lib/lua-parser/parser.lua:408 -if not r then -- ./lib/lua-parser/parser.lua:409 -return false -- ./lib/lua-parser/parser.lua:410 -end -- ./lib/lua-parser/parser.lua:410 -return true, r -- ./lib/lua-parser/parser.lua:412 +elseif last["tag"]:match("Expr$") then -- ./lib/lua-parser/parser.lua:369 +local r = searchEndRec({ last }) -- ./lib/lua-parser/parser.lua:370 +if r then -- ./lib/lua-parser/parser.lua:371 +for j = 2, # r, 1 do -- ./lib/lua-parser/parser.lua:372 +table["insert"](block, i + j - 1, r[j]) -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:373 +end -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:373 +return block, i -- ./lib/lua-parser/parser.lua:375 +end -- ./lib/lua-parser/parser.lua:375 +elseif last["tag"] == "Function" then -- ./lib/lua-parser/parser.lua:377 +local r = searchEndRec(last[2]) -- ./lib/lua-parser/parser.lua:378 +if r then -- ./lib/lua-parser/parser.lua:379 +return block, i -- ./lib/lua-parser/parser.lua:380 +end -- ./lib/lua-parser/parser.lua:380 +end -- ./lib/lua-parser/parser.lua:380 +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 -- ./lib/lua-parser/parser.lua:385 +local blocks -- ./lib/lua-parser/parser.lua:386 +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 -- ./lib/lua-parser/parser.lua:388 +blocks = stat -- ./lib/lua-parser/parser.lua:389 +elseif stat["tag"]:match("^Do") then -- ./lib/lua-parser/parser.lua:390 +blocks = { stat } -- ./lib/lua-parser/parser.lua:391 +end -- ./lib/lua-parser/parser.lua:391 +for _, iblock in ipairs(blocks) do -- ./lib/lua-parser/parser.lua:394 +if iblock["tag"] == "Block" then -- blocks -- ./lib/lua-parser/parser.lua:395 +local oldLen = # iblock -- ./lib/lua-parser/parser.lua:396 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./lib/lua-parser/parser.lua:397 +if newiBlock then -- if end in the block -- ./lib/lua-parser/parser.lua:398 +local p = i -- ./lib/lua-parser/parser.lua:399 +for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- move all statements after the newely added statements to the parent block -- ./lib/lua-parser/parser.lua:400 +p = p + 1 -- ./lib/lua-parser/parser.lua:401 +table["insert"](block, p, iblock[j]) -- ./lib/lua-parser/parser.lua:402 +iblock[j] = nil -- ./lib/lua-parser/parser.lua:403 +end -- ./lib/lua-parser/parser.lua:403 +if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:406 +for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:407 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:408 +end -- ./lib/lua-parser/parser.lua:408 +end -- ./lib/lua-parser/parser.lua:408 +return block, i -- ./lib/lua-parser/parser.lua:412 end -- ./lib/lua-parser/parser.lua:412 -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match -- ./lib/lua-parser/parser.lua:415 -if canFollow then -- ./lib/lua-parser/parser.lua:416 -return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:419 -else -- ./lib/lua-parser/parser.lua:419 -return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:423 -end -- ./lib/lua-parser/parser.lua:423 -end -- ./lib/lua-parser/parser.lua:423 -local function expectBlockWithEnd(label) -- can't work *optionnaly* with SingleStat unfortunatly -- ./lib/lua-parser/parser.lua:427 -return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./lib/lua-parser/parser.lua:429 -end -- ./lib/lua-parser/parser.lua:429 -local function maybeBlockWithEnd() -- same as above but don't error if it doesn't match -- ./lib/lua-parser/parser.lua:432 -return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./lib/lua-parser/parser.lua:434 -end -- ./lib/lua-parser/parser.lua:434 -local G = { -- ./lib/lua-parser/parser.lua:438 -V("Lua"), -- ./lib/lua-parser/parser.lua:438 -["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./lib/lua-parser/parser.lua:439 +end -- ./lib/lua-parser/parser.lua:412 +end -- ./lib/lua-parser/parser.lua:412 +end -- ./lib/lua-parser/parser.lua:412 +end -- ./lib/lua-parser/parser.lua:412 +return nil -- ./lib/lua-parser/parser.lua:418 +end -- ./lib/lua-parser/parser.lua:418 +local function searchEnd(s, p, t) -- match time capture which try to restructure the AST to free an "end" for us -- ./lib/lua-parser/parser.lua:421 +local r = searchEndRec(fixStructure(t)) -- ./lib/lua-parser/parser.lua:422 +if not r then -- ./lib/lua-parser/parser.lua:423 +return false -- ./lib/lua-parser/parser.lua:424 +end -- ./lib/lua-parser/parser.lua:424 +return true, r -- ./lib/lua-parser/parser.lua:426 +end -- ./lib/lua-parser/parser.lua:426 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match -- ./lib/lua-parser/parser.lua:429 +if canFollow then -- ./lib/lua-parser/parser.lua:430 +return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:433 +else -- ./lib/lua-parser/parser.lua:433 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:437 +end -- ./lib/lua-parser/parser.lua:437 +end -- ./lib/lua-parser/parser.lua:437 +local function expectBlockWithEnd(label) -- can't work *optionnaly* with SingleStat unfortunatly -- ./lib/lua-parser/parser.lua:441 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./lib/lua-parser/parser.lua:443 +end -- ./lib/lua-parser/parser.lua:443 +local function maybeBlockWithEnd() -- same as above but don't error if it doesn't match -- ./lib/lua-parser/parser.lua:446 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./lib/lua-parser/parser.lua:448 +end -- ./lib/lua-parser/parser.lua:448 +local stacks = { ["lexpr"] = {} } -- ./lib/lua-parser/parser.lua:452 +local function push(f) -- ./lib/lua-parser/parser.lua:454 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:455 +table["insert"](stacks[f], true) -- ./lib/lua-parser/parser.lua:456 +return true -- ./lib/lua-parser/parser.lua:457 +end) -- ./lib/lua-parser/parser.lua:457 +end -- ./lib/lua-parser/parser.lua:457 +local function pop(f) -- ./lib/lua-parser/parser.lua:460 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:461 +table["remove"](stacks[f]) -- ./lib/lua-parser/parser.lua:462 +return true -- ./lib/lua-parser/parser.lua:463 +end) -- ./lib/lua-parser/parser.lua:463 +end -- ./lib/lua-parser/parser.lua:463 +local function when(f) -- ./lib/lua-parser/parser.lua:466 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:467 +return # stacks[f] > 0 -- ./lib/lua-parser/parser.lua:468 +end) -- ./lib/lua-parser/parser.lua:468 +end -- ./lib/lua-parser/parser.lua:468 +local function set(f, patt) -- patt *must* succeed (or throw an error) to preserve stack integrity -- ./lib/lua-parser/parser.lua:471 +return push(f) * patt * pop(f) -- ./lib/lua-parser/parser.lua:472 +end -- ./lib/lua-parser/parser.lua:472 +local G = { -- ./lib/lua-parser/parser.lua:476 +V("Lua"), -- ./lib/lua-parser/parser.lua:476 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./lib/lua-parser/parser.lua:477 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 0, -- ./lib/lua-parser/parser.lua:440 -["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./lib/lua-parser/parser.lua:442 -["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("FuncCall") + V("Assignment") + V("LetStat") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./lib/lua-parser/parser.lua:447 -["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./lib/lua-parser/parser.lua:448 -["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./lib/lua-parser/parser.lua:450 -t["is_singlestatblock"] = true -- ./lib/lua-parser/parser.lua:450 -return t -- ./lib/lua-parser/parser.lua:450 -end, -- ./lib/lua-parser/parser.lua:450 -["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- used to check if something a valid block without throwing an error -- ./lib/lua-parser/parser.lua:451 -["IfStat"] = tagC("If", V("IfPart")), -- ./lib/lua-parser/parser.lua:453 -["IfPart"] = kw("if") * expect(V("Expr"), "ExprIf") * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:454 -["ElseIfPart"] = kw("elseif") * expect(V("Expr"), "ExprEIf") * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:455 -["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./lib/lua-parser/parser.lua:456 -["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./lib/lua-parser/parser.lua:458 -["WhileStat"] = tagC("While", kw("while") * expect(V("Expr"), "ExprWhile") * V("WhileBody")), -- ./lib/lua-parser/parser.lua:459 -["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./lib/lua-parser/parser.lua:460 -["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./lib/lua-parser/parser.lua:461 -["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./lib/lua-parser/parser.lua:463 -["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./lib/lua-parser/parser.lua:464 -["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./lib/lua-parser/parser.lua:466 -["ForIn"] = tagC("Forin", V("NameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./lib/lua-parser/parser.lua:467 -["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./lib/lua-parser/parser.lua:468 -["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./lib/lua-parser/parser.lua:470 -["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:471 -["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))), -- ./lib/lua-parser/parser.lua:472 -["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./lib/lua-parser/parser.lua:474 -["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))), -- ./lib/lua-parser/parser.lua:475 -["Assignment"] = tagC("Set", V("VarList") * V("BinOp") ^ - 1 * (P("=") / "=") * V("BinOp") ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./lib/lua-parser/parser.lua:477 -["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:479 -["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./lib/lua-parser/parser.lua:481 -["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./lib/lua-parser/parser.lua:482 -["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./lib/lua-parser/parser.lua:483 -["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- Cc({}) generates a bug since the {} would be shared across parses -- ./lib/lua-parser/parser.lua:486 -["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./lib/lua-parser/parser.lua:488 -["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./lib/lua-parser/parser.lua:489 -["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./lib/lua-parser/parser.lua:491 -["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:493 -["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:494 -["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./lib/lua-parser/parser.lua:496 -["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./lib/lua-parser/parser.lua:497 -["BreakStat"] = tagC("Break", kw("break")), -- ./lib/lua-parser/parser.lua:498 -["ContinueStat"] = tagC("Continue", kw("continue")), -- ./lib/lua-parser/parser.lua:499 -["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:500 -["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:502 -["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./lib/lua-parser/parser.lua:503 -["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./lib/lua-parser/parser.lua:505 -["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./lib/lua-parser/parser.lua:506 -["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./lib/lua-parser/parser.lua:507 -["Expr"] = V("OrExpr"), -- ./lib/lua-parser/parser.lua:509 -["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./lib/lua-parser/parser.lua:510 -["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./lib/lua-parser/parser.lua:511 -["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./lib/lua-parser/parser.lua:512 -["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./lib/lua-parser/parser.lua:513 -["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./lib/lua-parser/parser.lua:514 -["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./lib/lua-parser/parser.lua:515 -["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./lib/lua-parser/parser.lua:516 -["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:517 -["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./lib/lua-parser/parser.lua:518 -["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./lib/lua-parser/parser.lua:519 -["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./lib/lua-parser/parser.lua:521 -["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:522 -["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") + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./lib/lua-parser/parser.lua:532 -["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./lib/lua-parser/parser.lua:534 -["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:536 -return exp["tag"] == "Call" or exp["tag"] == "Invoke", exp -- ./lib/lua-parser/parser.lua:536 -end), -- ./lib/lua-parser/parser.lua:536 -["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:537 -return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./lib/lua-parser/parser.lua:537 -end), -- ./lib/lua-parser/parser.lua:537 -["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("Invoke") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("Invoke") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeIndexOrCall), -- ./lib/lua-parser/parser.lua:541 -["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./lib/lua-parser/parser.lua:544 -["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./lib/lua-parser/parser.lua:545 -["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./lib/lua-parser/parser.lua:547 -["Call"] = tagC("Call", V("FuncArgs")), -- ./lib/lua-parser/parser.lua:548 -["Invoke"] = tagC("Invoke", Cg(sym(":" * - P(":")) * expect(V("StrId"), "NameMeth") * expect(V("FuncArgs"), "MethArgs"))), -- ./lib/lua-parser/parser.lua:549 -["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./lib/lua-parser/parser.lua:550 -["SelfCall"] = tagC("Invoke", Cg(V("StrId") * V("FuncArgs"))), -- ./lib/lua-parser/parser.lua:551 -["FuncDef"] = (kw("function") * V("FuncBody")), -- ./lib/lua-parser/parser.lua:553 -["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./lib/lua-parser/parser.lua:556 -["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./lib/lua-parser/parser.lua:558 -["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:559 -["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./lib/lua-parser/parser.lua:561 -["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:563 -["FieldSep"] = sym(",") + sym(";"), -- ./lib/lua-parser/parser.lua:564 -["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./lib/lua-parser/parser.lua:566 -["SelfId"] = tagC("Id", sym("@") / "self"), -- ./lib/lua-parser/parser.lua:568 -["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./lib/lua-parser/parser.lua:569 -["StrId"] = tagC("String", V("Name")), -- ./lib/lua-parser/parser.lua:570 -["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./lib/lua-parser/parser.lua:573 -["Space"] = space ^ 1, -- ./lib/lua-parser/parser.lua:574 -["Comment"] = P("--") * V("LongStr") / function() -- ./lib/lua-parser/parser.lua:575 -return -- ./lib/lua-parser/parser.lua:575 +")) ^ 0, -- ./lib/lua-parser/parser.lua:478 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./lib/lua-parser/parser.lua:480 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("FuncCall") + V("Assignment") + V("LetStat") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./lib/lua-parser/parser.lua:485 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./lib/lua-parser/parser.lua:486 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./lib/lua-parser/parser.lua:488 +t["is_singlestatblock"] = true -- ./lib/lua-parser/parser.lua:488 +return t -- ./lib/lua-parser/parser.lua:488 +end, -- ./lib/lua-parser/parser.lua:488 +["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- used to check if something a valid block without throwing an error -- ./lib/lua-parser/parser.lua:489 +["IfStat"] = tagC("If", V("IfPart")), -- ./lib/lua-parser/parser.lua:491 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:492 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:493 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./lib/lua-parser/parser.lua:494 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./lib/lua-parser/parser.lua:496 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./lib/lua-parser/parser.lua:497 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./lib/lua-parser/parser.lua:498 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./lib/lua-parser/parser.lua:499 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./lib/lua-parser/parser.lua:501 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./lib/lua-parser/parser.lua:502 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./lib/lua-parser/parser.lua:504 +["ForIn"] = tagC("Forin", V("NameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./lib/lua-parser/parser.lua:505 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./lib/lua-parser/parser.lua:506 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./lib/lua-parser/parser.lua:508 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:509 +["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))), -- ./lib/lua-parser/parser.lua:510 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./lib/lua-parser/parser.lua:512 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))), -- ./lib/lua-parser/parser.lua:513 +["Assignment"] = tagC("Set", V("VarList") * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./lib/lua-parser/parser.lua:515 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:517 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./lib/lua-parser/parser.lua:519 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./lib/lua-parser/parser.lua:520 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./lib/lua-parser/parser.lua:521 +["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- Cc({}) generates a bug since the {} would be shared across parses -- ./lib/lua-parser/parser.lua:524 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./lib/lua-parser/parser.lua:526 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./lib/lua-parser/parser.lua:527 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./lib/lua-parser/parser.lua:529 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:531 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:532 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./lib/lua-parser/parser.lua:534 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./lib/lua-parser/parser.lua:535 +["BreakStat"] = tagC("Break", kw("break")), -- ./lib/lua-parser/parser.lua:536 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./lib/lua-parser/parser.lua:537 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:538 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:540 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./lib/lua-parser/parser.lua:541 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./lib/lua-parser/parser.lua:543 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./lib/lua-parser/parser.lua:544 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./lib/lua-parser/parser.lua:545 +["Expr"] = V("OrExpr"), -- ./lib/lua-parser/parser.lua:547 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./lib/lua-parser/parser.lua:548 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./lib/lua-parser/parser.lua:549 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./lib/lua-parser/parser.lua:550 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./lib/lua-parser/parser.lua:551 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./lib/lua-parser/parser.lua:552 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./lib/lua-parser/parser.lua:553 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./lib/lua-parser/parser.lua:554 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:555 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./lib/lua-parser/parser.lua:556 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./lib/lua-parser/parser.lua:557 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./lib/lua-parser/parser.lua:559 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:560 +["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", V("NameList") * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./lib/lua-parser/parser.lua:570 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./lib/lua-parser/parser.lua:572 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:574 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./lib/lua-parser/parser.lua:574 +end), -- ./lib/lua-parser/parser.lua:574 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:575 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./lib/lua-parser/parser.lua:575 +end), -- ./lib/lua-parser/parser.lua:575 +["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), -- ./lib/lua-parser/parser.lua:579 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./lib/lua-parser/parser.lua:582 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./lib/lua-parser/parser.lua:583 +["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")), -- ./lib/lua-parser/parser.lua:587 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./lib/lua-parser/parser.lua:589 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./lib/lua-parser/parser.lua:591 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./lib/lua-parser/parser.lua:592 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./lib/lua-parser/parser.lua:593 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./lib/lua-parser/parser.lua:595 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./lib/lua-parser/parser.lua:598 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./lib/lua-parser/parser.lua:600 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:601 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./lib/lua-parser/parser.lua:603 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:605 +["FieldSep"] = sym(",") + sym(";"), -- ./lib/lua-parser/parser.lua:606 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./lib/lua-parser/parser.lua:608 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./lib/lua-parser/parser.lua:610 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./lib/lua-parser/parser.lua:611 +["StrId"] = tagC("String", V("Name")), -- ./lib/lua-parser/parser.lua:612 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./lib/lua-parser/parser.lua:615 +["Space"] = space ^ 1, -- ./lib/lua-parser/parser.lua:616 +["Comment"] = P("--") * V("LongStr") / function() -- ./lib/lua-parser/parser.lua:617 +return -- ./lib/lua-parser/parser.lua:617 end + P("--") * (P(1) - P("\ -")) ^ 0, -- ./lib/lua-parser/parser.lua:576 -["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./lib/lua-parser/parser.lua:578 -["Reserved"] = V("Keywords") * - V("IdRest"), -- ./lib/lua-parser/parser.lua:579 -["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./lib/lua-parser/parser.lua:583 -["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./lib/lua-parser/parser.lua:584 -["IdStart"] = alpha + P("_"), -- ./lib/lua-parser/parser.lua:585 -["IdRest"] = alnum + P("_"), -- ./lib/lua-parser/parser.lua:586 -["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./lib/lua-parser/parser.lua:588 -["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./lib/lua-parser/parser.lua:589 -["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./lib/lua-parser/parser.lua:591 -["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./lib/lua-parser/parser.lua:593 -["DeciHex"] = P(".") * xdigit ^ 0, -- ./lib/lua-parser/parser.lua:594 -["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:595 -["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:596 -["Int"] = digit ^ 1, -- ./lib/lua-parser/parser.lua:597 -["String"] = token(V("ShortStr") + V("LongStr")), -- ./lib/lua-parser/parser.lua:599 +")) ^ 0, -- ./lib/lua-parser/parser.lua:618 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./lib/lua-parser/parser.lua:620 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./lib/lua-parser/parser.lua:621 +["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./lib/lua-parser/parser.lua:625 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./lib/lua-parser/parser.lua:626 +["IdStart"] = alpha + P("_"), -- ./lib/lua-parser/parser.lua:627 +["IdRest"] = alnum + P("_"), -- ./lib/lua-parser/parser.lua:628 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./lib/lua-parser/parser.lua:630 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./lib/lua-parser/parser.lua:631 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./lib/lua-parser/parser.lua:633 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./lib/lua-parser/parser.lua:635 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./lib/lua-parser/parser.lua:636 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:637 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:638 +["Int"] = digit ^ 1, -- ./lib/lua-parser/parser.lua:639 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./lib/lua-parser/parser.lua:641 ["ShortStr"] = P("\"") * Cs((V("EscSeq") + (P(1) - S("\"\ "))) ^ 0) * expect(P("\""), "Quote") + P("'") * Cs((V("EscSeq") + (P(1) - S("'\ -"))) ^ 0) * expect(P("'"), "Quote"), -- ./lib/lua-parser/parser.lua:601 +"))) ^ 0) * expect(P("'"), "Quote"), -- ./lib/lua-parser/parser.lua:643 ["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")), -- ./lib/lua-parser/parser.lua:631 -["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./lib/lua-parser/parser.lua:634 -return s -- ./lib/lua-parser/parser.lua:634 -end, -- ./lib/lua-parser/parser.lua:634 +" + 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")), -- ./lib/lua-parser/parser.lua:673 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./lib/lua-parser/parser.lua:676 +return s -- ./lib/lua-parser/parser.lua:676 +end, -- ./lib/lua-parser/parser.lua:676 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 1, -- ./lib/lua-parser/parser.lua:635 -["Close"] = "]" * C(V("Equals")) * "]", -- ./lib/lua-parser/parser.lua:636 -["Equals"] = P("=") ^ 0, -- ./lib/lua-parser/parser.lua:637 -["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./lib/lua-parser/parser.lua:638 -return # openEq == # closeEq -- ./lib/lua-parser/parser.lua:638 -end), -- ./lib/lua-parser/parser.lua:638 -["OrOp"] = kw("or") / "or", -- ./lib/lua-parser/parser.lua:640 -["AndOp"] = kw("and") / "and", -- ./lib/lua-parser/parser.lua:641 -["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./lib/lua-parser/parser.lua:647 -["BOrOp"] = sym("|") / "bor", -- ./lib/lua-parser/parser.lua:648 -["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./lib/lua-parser/parser.lua:649 -["BAndOp"] = sym("&") / "band", -- ./lib/lua-parser/parser.lua:650 -["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./lib/lua-parser/parser.lua:652 -["ConcatOp"] = sym("..") / "concat", -- ./lib/lua-parser/parser.lua:653 -["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./lib/lua-parser/parser.lua:655 -["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./lib/lua-parser/parser.lua:659 -["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./lib/lua-parser/parser.lua:663 -["PowOp"] = sym("^") / "pow", -- ./lib/lua-parser/parser.lua:664 -["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./lib/lua-parser/parser.lua:665 -} -- ./lib/lua-parser/parser.lua:665 -local parser = {} -- ./lib/lua-parser/parser.lua:668 -local validator = require("lib.lua-parser.validator") -- ./lib/lua-parser/parser.lua:670 -local validate = validator["validate"] -- ./lib/lua-parser/parser.lua:671 -local syntaxerror = validator["syntaxerror"] -- ./lib/lua-parser/parser.lua:672 -parser["parse"] = function(subject, filename) -- ./lib/lua-parser/parser.lua:674 -local errorinfo = { -- ./lib/lua-parser/parser.lua:675 -["subject"] = subject, -- ./lib/lua-parser/parser.lua:675 -["filename"] = filename -- ./lib/lua-parser/parser.lua:675 -} -- ./lib/lua-parser/parser.lua:675 -lpeg["setmaxstack"](1000) -- ./lib/lua-parser/parser.lua:676 -local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./lib/lua-parser/parser.lua:677 -if not ast then -- ./lib/lua-parser/parser.lua:678 -local errmsg = labels[label][2] -- ./lib/lua-parser/parser.lua:679 -return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./lib/lua-parser/parser.lua:680 -end -- ./lib/lua-parser/parser.lua:680 -return validate(ast, errorinfo) -- ./lib/lua-parser/parser.lua:682 -end -- ./lib/lua-parser/parser.lua:682 -return parser -- ./lib/lua-parser/parser.lua:685 -end -- ./lib/lua-parser/parser.lua:685 -local parser = _() or parser -- ./lib/lua-parser/parser.lua:689 -package["loaded"]["lib.lua-parser.parser"] = parser or true -- ./lib/lua-parser/parser.lua:690 +") ^ - 1, -- ./lib/lua-parser/parser.lua:677 +["Close"] = "]" * C(V("Equals")) * "]", -- ./lib/lua-parser/parser.lua:678 +["Equals"] = P("=") ^ 0, -- ./lib/lua-parser/parser.lua:679 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./lib/lua-parser/parser.lua:680 +return # openEq == # closeEq -- ./lib/lua-parser/parser.lua:680 +end), -- ./lib/lua-parser/parser.lua:680 +["OrOp"] = kw("or") / "or", -- ./lib/lua-parser/parser.lua:682 +["AndOp"] = kw("and") / "and", -- ./lib/lua-parser/parser.lua:683 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./lib/lua-parser/parser.lua:689 +["BOrOp"] = sym("|") / "bor", -- ./lib/lua-parser/parser.lua:690 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./lib/lua-parser/parser.lua:691 +["BAndOp"] = sym("&") / "band", -- ./lib/lua-parser/parser.lua:692 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./lib/lua-parser/parser.lua:694 +["ConcatOp"] = sym("..") / "concat", -- ./lib/lua-parser/parser.lua:695 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./lib/lua-parser/parser.lua:697 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./lib/lua-parser/parser.lua:701 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./lib/lua-parser/parser.lua:705 +["PowOp"] = sym("^") / "pow", -- ./lib/lua-parser/parser.lua:706 +["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./lib/lua-parser/parser.lua:707 +} -- ./lib/lua-parser/parser.lua:707 +local parser = {} -- ./lib/lua-parser/parser.lua:710 +local validator = require("lib.lua-parser.validator") -- ./lib/lua-parser/parser.lua:712 +local validate = validator["validate"] -- ./lib/lua-parser/parser.lua:713 +local syntaxerror = validator["syntaxerror"] -- ./lib/lua-parser/parser.lua:714 +parser["parse"] = function(subject, filename) -- ./lib/lua-parser/parser.lua:716 +local errorinfo = { -- ./lib/lua-parser/parser.lua:717 +["subject"] = subject, -- ./lib/lua-parser/parser.lua:717 +["filename"] = filename -- ./lib/lua-parser/parser.lua:717 +} -- ./lib/lua-parser/parser.lua:717 +lpeg["setmaxstack"](1000) -- ./lib/lua-parser/parser.lua:718 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./lib/lua-parser/parser.lua:719 +if not ast then -- ./lib/lua-parser/parser.lua:720 +local errmsg = labels[label][2] -- ./lib/lua-parser/parser.lua:721 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./lib/lua-parser/parser.lua:722 +end -- ./lib/lua-parser/parser.lua:722 +return validate(ast, errorinfo) -- ./lib/lua-parser/parser.lua:724 +end -- ./lib/lua-parser/parser.lua:724 +return parser -- ./lib/lua-parser/parser.lua:727 +end -- ./lib/lua-parser/parser.lua:727 +local parser = _() or parser -- ./lib/lua-parser/parser.lua:731 +package["loaded"]["lib.lua-parser.parser"] = parser or true -- ./lib/lua-parser/parser.lua:732 local candran = { ["VERSION"] = "0.10.0" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 @@ -3643,7 +4061,10 @@ env["candran"] = candran -- candran.can:79 env["output"] = "" -- candran.can:81 env["import"] = function(modpath, margs) -- candran.can:88 if margs == nil then margs = {} end -- candran.can:88 -local filepath = assert(util["search"](modpath), "No module named \"" .. modpath .. "\"") -- candran.can:89 +local filepath = assert(util["search"](modpath, { -- candran.can:89 +"can", -- candran.can:89 +"lua" -- candran.can:89 +}), "No module named \"" .. modpath .. "\"") -- candran.can:89 local f = io["open"](filepath) -- candran.can:92 if not f then -- candran.can:93 error("Can't open the module file to import") -- candran.can:93 diff --git a/compiler/lua51.can b/compiler/lua51.can index 2af7629..2238d70 100644 --- a/compiler/lua51.can +++ b/compiler/lua51.can @@ -1,3 +1,5 @@ +targetName = "Lua 5.1" + states.continue = {} -- when in a loop that use continue CONTINUE_START = () @@ -19,12 +21,9 @@ tags.Break = () end end -tags.Goto = () - error("Lua 5.1 does not support the goto keyword") -end -tags.Label = () - error("Lua 5.1 does not support labels") -end +-- Unsuported features +tags.Goto = nil +tags.Label = nil #local patch = output #output = "" diff --git a/compiler/lua53.can b/compiler/lua53.can index 3e1ae64..656ac0e 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -1,3 +1,5 @@ +local targetName = "Lua 5.3" + return function(code, ast, options) --- Line mapping local lastInputPos = 1 -- last token position in the input code @@ -9,7 +11,7 @@ return function(code, ast, options) local indentLevel = 0 -- Returns a newline. local function newline() - local r = options.newline .. string.rep(options.indentation, indentLevel) + 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") @@ -25,7 +27,7 @@ return function(code, ast, options) prevLinePos = lastInputPos - r = " -- " .. lastSource .. ":" .. lastLine .. r + r = " -- "..lastSource..":"..lastLine..r end return r end @@ -46,7 +48,7 @@ return function(code, ast, options) -- 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) if not required[mod] then - requireStr ..= "local " .. options.variablePrefix .. name .. (" = require(%q)"):format(mod) .. (field and "."..field or "") .. options.newline + requireStr ..= "local "..options.variablePrefix..name..(" = require(%q)"):format(mod)..(field and "."..field or "")..options.newline required[mod] = true end end @@ -54,12 +56,13 @@ return function(code, ast, options) --- Variable management -- Returns the prefixed variable name. local function var(name) - return options.variablePrefix .. name + return options.variablePrefix..name end --- AST traversal helpers - local loop = { "While", "Repeat", "Fornum", "Forin" } -- loops tags - local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags + 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={}) @@ -85,6 +88,50 @@ return function(code, ast, options) 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 + --- State stacks -- Used for context-sensitive syntax. local states = { @@ -117,16 +164,16 @@ return function(code, ast, options) --- Lua function calls writer local UNPACK = (list, i, j) -- table.unpack - return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" + 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 a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" + return "do"..indent().."local a = table.pack("..toAppend..")"..newline().."table.move(a, 1, a.n, #"..t.."+1, "..t..")"..unindent().."end" end local CONTINUE_START = () -- at the start of loops using continue - return "do" .. indent() + return "do"..indent() end local CONTINUE_STOP = () -- at the start of loops using continue - return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" + return unindent().."end"..newline().."::"..var"continue".."::" end --- Tag constructors @@ -140,16 +187,16 @@ return function(code, ast, options) end local r = "" if hasPush then - r ..= push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline() + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() end for i=1, #t-1, 1 do - r ..= lua(t[i]) .. newline() + 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") + r ..= newline().."return "..UNPACK(var"push")..pop("push") end return r end, @@ -158,81 +205,122 @@ return function(code, ast, options) -- Do{ stat* } Do = (t) - return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" + return "do"..indent()..lua(t, "Block")..unindent().."end" end, -- Set{ {lhs+} (opid? = opid?)? {expr+} } Set = (t) if #t == 2 then - return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") + return lua(t[1], "_lhs").." = "..lua(t[2], "_lhs") elseif #t == 3 then - return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") + return lua(t[1], "_lhs").." = "..lua(t[3], "_lhs") elseif #t == 4 then if t[3] == "=" then - local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], { tag = "Paren", t[4][1] } }, "Op") + local r = lua(t[1], "_lhs").." = "..lua({ t[2], t[1][1], { tag = "Paren", t[4][1] } }, "Op") for i=2, math.min(#t[4], #t[1]), 1 do - r ..= ", " .. lua({ t[2], t[1][i], { tag = "Paren", t[4][i] } }, "Op") + r ..= ", "..lua({ t[2], t[1][i], { tag = "Paren", t[4][i] } }, "Op") end return r else - local r = lua(t[1], "_lhs") .. " = " .. lua({ t[3], { tag = "Paren", t[4][1] }, t[1][1] }, "Op") + local r = lua(t[1], "_lhs").." = "..lua({ t[3], { tag = "Paren", t[4][1] }, t[1][1] }, "Op") for i=2, math.min(#t[4], #t[1]), 1 do - r ..= ", " .. lua({ t[3], { tag = "Paren", t[4][i] }, t[1][i] }, "Op") + r ..= ", "..lua({ t[3], { tag = "Paren", t[4][i] }, t[1][i] }, "Op") end return r end else -- You are mad. - local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], { tag = "Op", t[4], { tag = "Paren", t[5][1] }, t[1][1] } }, "Op") + local r = lua(t[1], "_lhs").." = "..lua({ t[2], t[1][1], { tag = "Op", t[4], { tag = "Paren", t[5][1] }, t[1][1] } }, "Op") for i=2, math.min(#t[5], #t[1]), 1 do - r ..= ", " .. lua({ t[2], t[1][i], { tag = "Op", t[4], { tag = "Paren", t[5][i] }, t[1][i] } }, "Op") + r ..= ", "..lua({ t[2], t[1][i], { tag = "Op", t[4], { tag = "Paren", t[5][i] }, t[1][i] } }, "Op") end return r end end, -- While{ expr block } While = (t) + local r = "" local hasContinue = any(t[2], { "Continue" }, loop) - local r = "while " .. lua(t[1]) .. " do" .. indent() + 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]) + r ..= lua(t[2]) if hasContinue then r ..= CONTINUE_STOP() end - r ..= unindent() .. "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() + local r = "repeat"..indent() if hasContinue then r ..= CONTINUE_START() end - r .. = lua(t[1]) + r ..= lua(t[1]) if hasContinue then r ..= CONTINUE_STOP() end - r ..= unindent() .. "until " .. lua(t[2]) + r ..= unindent().."until "..lua(t[2]) return r end, - -- If{ (expr block)+ block? } + -- If{ (lexpr block)+ block? } If = (t) - local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() + 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 - r ..= "elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i+1]) .. unindent() + 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() + r ..= "else"..indent()..lua(t[#t])..unindent() end - return r .. "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]) + 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() + r ..= ", "..lua(t[4]).." do"..indent() if hasContinue then r ..= CONTINUE_START() end @@ -240,10 +328,10 @@ return function(code, ast, options) if hasContinue then r ..= CONTINUE_STOP() end - return r .. unindent() .. "end" + return r..unindent().."end" else local hasContinue = any(t[4], { "Continue" }, loop) - r ..= " do" .. indent() + r ..= " do"..indent() if hasContinue then r ..= CONTINUE_START() end @@ -251,13 +339,13 @@ return function(code, ast, options) if hasContinue then r ..= CONTINUE_STOP() end - return r .. unindent() .. "end" + return r..unindent().."end" end end, -- Forin{ {ident+} {expr+} block } Forin = (t) local hasContinue = any(t[3], { "Continue" }, loop) - local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() + local r = "for "..lua(t[1], "_lhs").." in "..lua(t[2], "_lhs").." do"..indent() if hasContinue then r ..= CONTINUE_START() end @@ -265,7 +353,7 @@ return function(code, ast, options) if hasContinue then r ..= CONTINUE_STOP() end - return r .. unindent() .. "end" + return r..unindent().."end" end, -- Local{ {ident+} {expr+}? } Local = (t) @@ -278,12 +366,12 @@ return function(code, ast, options) -- Let{ {ident+} {expr+}? } Let = (t) local nameList = lua(t[1], "_lhs") - local r = "local " .. nameList + local r = "local "..nameList if t[2][1] then - if any(t[2], { "Function", "Table", "Paren" }) then -- predeclaration doesn't matter otherwise - r ..= newline() .. nameList .. " = " .. lua(t[2], "_lhs") + if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here + r ..= " = "..lua(t[2], "_lhs") else - r ..= " = " .. lua(t[2], "_lhs") + r ..= newline()..nameList.." = "..lua(t[2], "_lhs") end end return r @@ -294,11 +382,11 @@ return function(code, ast, options) end, -- Goto{ } Goto = (t) - return "goto " .. lua(t, "Id") + return "goto "..lua(t, "Id") end, -- Label{ } Label = (t) - return "::" .. lua(t, "Id") .. "::" + return "::"..lua(t, "Id").."::" end, -- Return{ } Return = (t) @@ -306,9 +394,9 @@ return function(code, ast, options) if push then local r = "" for _, val in ipairs(t) do - r ..= push .. "[#" .. push .. "+1] = " .. lua(val) .. newline() + r ..= push.."[#"..push.."+1] = "..lua(val)..newline() end - return r .. "return " .. UNPACK(push) + return r.."return "..UNPACK(push) else return "return "..lua(t, "_lhs") end @@ -318,13 +406,13 @@ return function(code, ast, options) 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() + r ..= var.."[#"..var.."+1] = "..lua(t[i])..newline() end if t[#t] then - if t[#t].tag == "Call" or t[#t].tag == "Invoke" then + if t[#t].tag == "Call" then r ..= APPEND(var, lua(t[#t])) else - r ..= var .. "[#" .. var .. "+1] = " .. lua(t[#t]) + r ..= var.."[#"..var.."+1] = "..lua(t[#t]) end end return r @@ -335,7 +423,7 @@ return function(code, ast, options) end, -- Continue Continue = () - return "goto " .. var("continue") + return "goto "..var"continue" end, -- apply (below) @@ -359,7 +447,7 @@ return function(code, ast, options) end, -- String{ } String = (t) - return ("%q"):format(t[1]) + return "%q":format(t[1]) end, -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } _functionWithoutKeyword = (t) @@ -369,7 +457,7 @@ return function(code, ast, options) 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") + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") indentLevel -= 1 r ..= id else @@ -379,66 +467,66 @@ return function(code, ast, options) 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") + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") indentLevel -= 1 r ..= ", " ..id else - r ..= ", " .. lua(t[1][i]) + r ..= ", "..lua(t[1][i]) end end end - r ..= ")" .. indent() + r ..= ")"..indent() for _, d in ipairs(decl) do - r ..= d .. newline() + 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() + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() else - push("push", false) -- no push here (make sure higher push don't affect us) + 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")) + r ..= newline().."return "..UNPACK(var"push") end pop("push") - return r .. unindent() .. "end" + return r..unindent().."end" end, Function = (t) - return "function" .. lua(t, "_functionWithoutKeyword") + return "function"..lua(t, "_functionWithoutKeyword") end, -- Table{ ( `Pair{ expr expr } | expr )* } Pair = (t) - return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) + return "["..lua(t[1]).."] = "..lua(t[2]) end, Table = (t) if #t == 0 then return "{}" elseif #t == 1 then - return "{ " .. lua(t, "_lhs") .. " }" + return "{ "..lua(t, "_lhs").." }" else - return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" + 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") + 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]) + 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]) + r = lua(t[2]).." "..tags._opid[t[1]].." "..lua(t[3]) else r = tags._opid[t[1]](t[2], t[3]) end @@ -447,27 +535,51 @@ return function(code, ast, options) end, -- Paren{ expr } Paren = (t) - return "(" .. lua(t[1]) .. ")" + 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() + local r = "(function()"..indent() if hasPush then - r ..= push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline() + 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")) + r ..= newline().."return "..UNPACK(var"push") end pop("push") - r ..= unindent() .. "end)()" + r ..= unindent().."end)()" return r end, -- DoExpr{ stat* } @@ -509,18 +621,23 @@ return function(code, ast, options) -- Call{ expr expr* } Call = (t) if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" + return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" + 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) .. ")" + return lua(t[1]).."("..lua(t, "_lhs", 2)..")" end end, - - -- Invoke{ expr `String{ } expr* } - Invoke = (t) - if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1]).."):"..lua(t[2], "Id").."("..lua(t, "_lhs", 3)..")" - else - return lua(t[1])..":"..lua(t[2], "Id").."("..lua(t, "_lhs", 3)..")" + -- 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, @@ -530,7 +647,7 @@ return function(code, ast, options) if t[start] then r = lua(t[start]) for i=start+1, #t, 1 do - r ..= "," .. (newlines and newline() or " ") .. lua(t[i]) + r ..= ","..(newlines and newline() or " ")..lua(t[i]) end else r = "" @@ -549,6 +666,29 @@ return function(code, ast, options) 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 = { @@ -560,12 +700,12 @@ return function(code, ast, options) } }, { __index = (self, key) - error("don't know how to compile a "..tostring(key).." to Lua 5.3") + error("don't know how to compile a "..tostring(key).." to "..targetName) end }) #placeholder("patch") - local code = lua(ast) .. newline() - return requireStr .. code + local code = lua(ast)..newline() + return requireStr..code end diff --git a/compiler/luajit.can b/compiler/luajit.can index 51a720f..79e85be 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -1,3 +1,5 @@ +targetName = "luajit" + UNPACK = (list, i, j) return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" end diff --git a/ideas.txt b/ideas.txt index 2a91999..6c3f6c8 100644 --- a/ideas.txt +++ b/ideas.txt @@ -8,7 +8,7 @@ To be implemented, theese need to: * be significantly useful compared to existing Candran/Lua code. * be useful without having to rewrite APIs specifically for Candran. Candran intends to make Lua easier, not supersede it. -Example currently rejected ideas: +Example rejected ideas: * Python-style function decorators (implemented in Candran 0.1.0): Useless 95% of the time because most Lua APIs applying something to a function are used like applySomething(someArg,func) instead of func=applySomething(someArg)(func). This could be adapted, but this will mean unecessary named functions in the environment and it will only works when the decorator returns the functions. @@ -48,15 +48,6 @@ finally clean() end -* Safe navigation operator -local name = articles?[0].author?.name (?[] and ?. index opeators) -or -local zip = lottery.drawWinner?().address?.zipcode (expr? existence test suffix) - -if one is nil, returns nil - -See http://coffeescript.org/#existential-operator - * static type checking local a = externalFunc() -- unknown if a == "hey" then @@ -103,13 +94,3 @@ meh * Other potential inspiration https://www.ruby-lang.org/fr/ - -* If with assignement -if f = io.open("file") then - f:close() -end - -f is in the if scope - -* Method self bundler -obj:method -- returns (...) return method(obj, ...) end diff --git a/lib/lua-parser/parser.lua b/lib/lua-parser/parser.lua index c9d390d..e16d959 100644 --- a/lib/lua-parser/parser.lua +++ b/lib/lua-parser/parser.lua @@ -11,7 +11,7 @@ stat: | `Set{ {lhs+} (opid? = opid?)? {expr+} } -- lhs1, lhs2... op=op e1, e2... | `While{ expr block } -- while e do b end | `Repeat{ block expr } -- repeat b until e - | `If{ (expr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end + | `If{ (lexpr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end | `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{ {ident+} {expr+}? } -- local i1, i2... = e1, e2... @@ -36,10 +36,17 @@ expr: | `Op{ opid expr expr? } | `Paren{ expr } -- significant to cut multiple values returns | `TableCompr{ block } + | `MethodStub{ expr expr } + | `SafeMethodStub{ expr expr } + | `SafeIndex{ expr expr } | statexpr | apply | lhs +lexpr: + `LetExpr{ {ident+} {expr+}? } + | every node from expr + statexpr: `DoExpr{ stat* } | `WhileExpr{ expr block } -- while e do b end @@ -50,7 +57,7 @@ statexpr: apply: `Call{ expr expr* } - | `Invoke{ expr `String{ } expr* } + | `SafeCall{ expr expr* } lhs: `Id{ } | `Index{ expr expr } @@ -255,25 +262,32 @@ local function insertIndex (t, index) return { tag = "Index", pos = t.pos, [1] = t, [2] = index } end -local function markMethod(t, method) +local function markMethod (t, method) if method then return { tag = "Index", pos = t.pos, is_method = true, [1] = t, [2] = method } end return t end -local function makeIndexOrCall (t1, t2) - if t2.tag == "Call" or t2.tag == "Invoke" then +local function makeSuffixedExpr (t1, t2) + if t2.tag == "Call" or t2.tag == "SafeCall" then local t = { tag = t2.tag, pos = t1.pos, [1] = t1 } for k, v in ipairs(t2) do table.insert(t, v) end return t + elseif t2.tag == "MethodStub" or t2.tag == "SafeMethodStub" then + return { tag = t2.tag, pos = t1.pos, [1] = t1, [2] = t2[1] } + elseif t2.tag == "SafeDotIndex" or t2.tag == "SafeArrayIndex" then + return { tag = "SafeIndex", pos = t1.pos, [1] = t1, [2] = t2[1] } + elseif t2.tag == "DotIndex" or t2.tag == "ArrayIndex" then + return { tag = "Index", pos = t1.pos, [1] = t1, [2] = t2[1] } + else + error("unexpected tag in suffixed expression") end - return { tag = "Index", pos = t1.pos, [1] = t1, [2] = t2[1] } end -local function fixShortFunc(t) +local function fixShortFunc (t) if t[1] == ":" then -- self method table.insert(t[2], 1, { tag = "Id", "self" }) table.remove(t, 1) @@ -283,12 +297,12 @@ local function fixShortFunc(t) return t end -local function statToExpr(t) -- tag a StatExpr +local function statToExpr (t) -- tag a StatExpr t.tag = t.tag .. "Expr" return t end -local function fixStructure(t) -- fix the AST structure if needed +local function fixStructure (t) -- fix the AST structure if needed local i = 1 while i <= #t do if type(t[i]) == "table" then @@ -309,7 +323,7 @@ local function fixStructure(t) -- fix the AST structure if needed return t 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) +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 @@ -404,7 +418,7 @@ local function searchEndRec(block, isRecCall) -- recursively search potential "e return nil end -local function searchEnd(s, p, t) -- match time capture which try to restructure the AST to free an "end" for us +local function searchEnd (s, p, t) -- match time capture which try to restructure the AST to free an "end" for us local r = searchEndRec(fixStructure(t)) if not r then return false @@ -412,7 +426,7 @@ local function searchEnd(s, p, t) -- match time capture which try to restructure return true, r end -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match +local function expectBlockOrSingleStatWithStartEnd (start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match if canFollow then return (-start * V"SingleStatBlock" * canFollow^-1) + (expect(start, startLabel) * ((V"Block" * (canFollow + kw("end"))) @@ -424,16 +438,40 @@ local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, end end -local function expectBlockWithEnd(label) -- can't work *optionnaly* with SingleStat unfortunatly +local function expectBlockWithEnd (label) -- can't work *optionnaly* with SingleStat unfortunatly return (V"Block" * kw("end")) + (Cmt(V"Block", searchEnd) + throw(label)) end -local function maybeBlockWithEnd() -- same as above but don't error if it doesn't match +local function maybeBlockWithEnd () -- same as above but don't error if it doesn't match return (V"BlockNoErr" * kw("end")) + Cmt(V"BlockNoErr", searchEnd) end +local stacks = { + lexpr = {} +} +local function push (f) + return Cmt(P"", function() + table.insert(stacks[f], true) + return true + end) +end +local function pop (f) + return Cmt(P"", function() + table.remove(stacks[f]) + return true + end) +end +local function when (f) + return Cmt(P"", function() + return #stacks[f] > 0 + end) +end +local function set (f, patt) -- patt *must* succeed (or throw an error) to preserve stack integrity + return push(f) * patt * pop(f) +end + -- grammar local G = { V"Lua", Lua = (V"Shebang"^-1 * V"Skip" * V"Block" * expect(P(-1), "Extra")) / fixStructure; @@ -451,12 +489,12 @@ local G = { V"Lua", BlockNoErr = tagC("Block", V"Stat"^0 * ((V"RetStat" + V"ImplicitPushStat") * sym(";")^-1)^-1); -- used to check if something a valid block without throwing an error IfStat = tagC("If", V"IfPart"); - IfPart = kw("if") * expect(V"Expr", "ExprIf") * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V"ElseIfPart" + V"ElsePart"); - ElseIfPart = kw("elseif") * expect(V"Expr", "ExprEIf") * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V"ElseIfPart" + V"ElsePart"); + IfPart = kw("if") * set("lexpr", expect(V"Expr", "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V"ElseIfPart" + V"ElsePart"); + ElseIfPart = kw("elseif") * set("lexpr", expect(V"Expr", "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V"ElseIfPart" + V"ElsePart"); ElsePart = kw("else") * expectBlockWithEnd("EndIf"); DoStat = kw("do") * expectBlockWithEnd("EndDo") / tagDo; - WhileStat = tagC("While", kw("while") * expect(V"Expr", "ExprWhile") * V"WhileBody"); + WhileStat = tagC("While", kw("while") * set("lexpr", expect(V"Expr", "ExprWhile")) * V"WhileBody"); WhileBody = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"); RepeatStat = tagC("Repeat", kw("repeat") * V"Block" * expect(kw("until"), "UntilRep") * expect(V"Expr", "ExprRep")); @@ -474,7 +512,7 @@ local G = { V"Lua", LetStat = kw("let") * expect(V"LetAssign", "DefLet"); LetAssign = tagC("Let", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))); - Assignment = tagC("Set", V"VarList" * V"BinOp"^-1 * (P"=" / "=") * V"BinOp"^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); + Assignment = tagC("Set", V"VarList" * V"BinOp"^-1 * (P"=" / "=") * ((V"BinOp" - P"-") + #(P"-" * V"Space") * V"BinOp")^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); FuncStat = tagC("Set", kw("function") * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat; FuncName = Cf(V"Id" * (sym(".") * expect(V"StrId", "NameFunc1"))^0, insertIndex) @@ -520,35 +558,39 @@ local G = { V"Lua", UnaryExpr = V"UnaryOp" * expect(V"UnaryExpr", "UnaryExpr") / unaryOp + V"PowExpr"; PowExpr = V"SimpleExpr" * (V"PowOp" * expect(V"UnaryExpr", "PowExpr"))^-1 / binaryOp; - - 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" - + V"ShortFuncDef" - + V"SuffixedExpr" - + V"StatExpr"; + 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", V"NameList" * sym("=") * -sym("=") * expect(V"ExprList", "EListLAssign"))) + + V"ShortFuncDef" + + V"SuffixedExpr" + + V"StatExpr"; StatExpr = (V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat") / statToExpr; - FuncCall = Cmt(V"SuffixedExpr", function(s, i, exp) return exp.tag == "Call" or exp.tag == "Invoke", exp end); + FuncCall = Cmt(V"SuffixedExpr", function(s, i, exp) return exp.tag == "Call" or exp.tag == "SafeCall", exp end); VarExpr = Cmt(V"SuffixedExpr", function(s, i, exp) return exp.tag == "Id" or exp.tag == "Index", exp end); - SuffixedExpr = Cf(V"PrimaryExpr" * (V"Index" + V"Invoke" + V"Call")^0 - + V"NoCallPrimaryExpr" * -V"Call" * (V"Index" + V"Invoke" + V"Call")^0 - + V"NoCallPrimaryExpr", makeIndexOrCall); + 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); PrimaryExpr = V"SelfId" * (V"SelfCall" + V"SelfIndex") + V"Id" + tagC("Paren", sym("(") * expect(V"Expr", "ExprParen") * expect(sym(")"), "CParenExpr")); NoCallPrimaryExpr = tagC("String", V"String") + V"Table" + V"TableCompr"; Index = tagC("DotIndex", sym("." * -P".") * expect(V"StrId", "NameIndex")) - + tagC("ArrayIndex", sym("[" * -P(S"=[")) * expect(V"Expr", "ExprIndex") * expect(sym("]"), "CBracketIndex")); - Call = tagC("Call", V"FuncArgs"); - Invoke = tagC("Invoke", Cg(sym(":" * -P":") * expect(V"StrId", "NameMeth") * expect(V"FuncArgs", "MethArgs"))); + + 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")); + MethodStub = tagC("MethodStub", sym(":" * -P":") * expect(V"StrId", "NameMeth")) + + tagC("SafeMethodStub", sym("?:" * -P":") * expect(V"StrId", "NameMeth")); + Call = tagC("Call", V"FuncArgs") + + tagC("SafeCall", P"?" * V"FuncArgs"); + SelfCall = tagC("MethodStub", V"StrId") * V"Call"; SelfIndex = tagC("DotIndex", V"StrId"); - SelfCall = tagC("Invoke", Cg(V"StrId" * V"FuncArgs")); FuncDef = (kw("function") * V"FuncBody"); FuncArgs = sym("(") * commaSep(V"Expr", "ArgList")^-1 * expect(sym(")"), "CParenArgs") diff --git a/lib/lua-parser/validator.lua b/lib/lua-parser/validator.lua index 7b4419a..2094446 100644 --- a/lib/lua-parser/validator.lua +++ b/lib/lua-parser/validator.lua @@ -158,16 +158,6 @@ local function traverse_call (env, call) return true end -local function traverse_invoke (env, invoke) - local status, msg = traverse_exp(env, invoke[1]) - if not status then return status, msg end - for i=3, #invoke do - status, msg = traverse_exp(env, invoke[i]) - if not status then return status, msg end - end - return true -end - local function traverse_assignment (env, stm) local status, msg = traverse_varlist(env, stm[1]) if not status then return status, msg end @@ -238,6 +228,18 @@ local function traverse_goto (env, stm) return true end +local function traverse_let (env, stm) + local status, msg = traverse_explist(env, stm[2]) + if not status then return status, msg end + return true +end + +local function traverse_letrec (env, stm) + local status, msg = traverse_exp(env, stm[2][1]) + if not status then return status, msg end + return true +end + local function traverse_if (env, stm) local len = #stm if len % 2 == 0 then @@ -266,18 +268,6 @@ local function traverse_label (env, stm) return true end -local function traverse_let (env, stm) - local status, msg = traverse_explist(env, stm[2]) - if not status then return status, msg end - return true -end - -local function traverse_letrec (env, stm) - local status, msg = traverse_exp(env, stm[2][1]) - if not status then return status, msg end - return true -end - local function traverse_repeat (env, stm) begin_loop(env) local status, msg = traverse_block(env, stm[1]) @@ -327,6 +317,22 @@ function traverse_varlist (env, varlist) return true end +local function traverse_methodstub (env, var) + local status, msg = traverse_exp(env, var[1]) + if not status then return status, msg end + status, msg = traverse_exp(env, var[2]) + if not status then return status, msg end + return true +end + +local function traverse_safeindex (env, var) + local status, msg = traverse_exp(env, var[1]) + if not status then return status, msg end + status, msg = traverse_exp(env, var[2]) + if not status then return status, msg end + return true +end + function traverse_exp (env, exp) local tag = exp.tag if tag == "Nil" or @@ -344,15 +350,17 @@ function traverse_exp (env, exp) return traverse_op(env, exp) elseif tag == "Paren" then -- `Paren{ expr } return traverse_paren(env, exp) - elseif tag == "Call" then -- `Call{ expr expr* } + elseif tag == "Call" or tag == "SafeCall" then -- `(Safe)Call{ expr expr* } return traverse_call(env, exp) - elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } - return traverse_invoke(env, exp) elseif tag == "Id" or -- `Id{ } tag == "Index" then -- `Index{ expr expr } return traverse_var(env, exp) + elseif tag == "SafeIndex" then -- `SafeIndex{ expr expr } + return traverse_safeindex(env, exp) elseif tag == "TableCompr" then -- `TableCompr{ block } return traverse_tablecompr(env, exp) + elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- `(Safe)MethodStub{ expr expr } + return traverse_methodstub(env, exp) elseif tag:match("Expr$") then -- `StatExpr{ ... } return traverse_statexpr(env, exp) else @@ -399,8 +407,6 @@ function traverse_stm (env, stm) return traverse_break(env, stm) elseif tag == "Call" then -- `Call{ expr expr* } return traverse_call(env, stm) - elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } - return traverse_invoke(env, stm) elseif tag == "Continue" then return traverse_continue(env, stm) elseif tag == "Push" then -- `Push{ * } diff --git a/lib/util.can b/lib/util.can index c19c448..2beb260 100644 --- a/lib/util.can +++ b/lib/util.can @@ -1,6 +1,6 @@ local util = {} -function util.search(modpath, exts={"can", "lua"}) +function util.search(modpath, exts={}) for _, ext in ipairs(exts) do for path in package.path:gmatch("[^;]+") do local fpath = path:gsub("%.lua", "."..ext):gsub("%?", (modpath:gsub("%.", "/"))) diff --git a/test/test.lua b/test/test.lua index ce3a7bd..e4f16b8 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1,4 +1,8 @@ local candran = dofile(arg[1] or "../candran.lua") +candran.default.indentation = "\t" +candran.default.mapLines = false + +local load = require("lib.util").load -- test helper local results = {} -- tests result @@ -10,15 +14,17 @@ local function test(name, candranCode, expectedResult, options) local success, code = pcall(candran.make, candranCode, options) if not success then self.result = "error" - self.message = "error while making code:\n"..code + self.message = "/!\\ error while making code:\n"..code return end -- load code - local success, func = pcall(loadstring or 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 self.result = "error" - self.message = "error while loading code:\n"..func + self.message = "/!\\ error while loading code:\n"..func.."\ngenerated code:\n"..code return end @@ -26,14 +32,14 @@ local function test(name, candranCode, expectedResult, options) local success, output = pcall(func) if not success then self.result = "error" - self.message = "error while running code:\n"..output + self.message = "/!\\ error while running code:\n"..output.."\ngenerated code:\n"..code return end -- check result if output ~= expectedResult then self.result = "fail" - self.message = "invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult) + self.message = "/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult).."; generated code:\n"..code return else self.result = "success" @@ -669,6 +675,154 @@ test("suffixable table comprehension array index", [[ return [@len=3]["len"] ]], 3) +-- let in condition expression +test("let in while condition, evaluation each iteration", [[ + local s = "" + local i = 0 + while (a = i+2) and i < 3 do + s = s .. tostring(a) + i = i + 1 + a = 0 + end + return s +]], "234") +test("let in while condition, scope", [[ + local s = "" + local i = 0 + while (a = i+2) and i < 3 do + s = s .. tostring(a) + i = i + 1 + a = 0 + end + return a +]], nil) +test("several let in while condition, evaluation order", [[ + local s = "" + local i = 0 + while (a = (b=i+1)+1) and i < 3 do + assert(b==i+1) + s = s .. tostring(a) + i = i + 1 + a = 0 + end + return s +]], "234") +test("several let in while condition, only test the first", [[ + local s = "" + local i = 0 + while (a,b = false,i) and i < 3 do + s = s .. tostring(a) + i = i + 1 + end + return s +]], "") + +test("let in if condition", [[ + if a = false then + error("condition was false") + elseif b = nil then + error("condition was nil") + elseif c = true then + return "ok" + elseif d = true then + error("should not be reachable") + end +]], "ok") +test("let in if condition, scope", [[ + local r + if a = false then + error("condition was false") + elseif b = nil then + error("condition was nil") + elseif c = true then + assert(a == false) + assert(d == nil) + r = "ok" + elseif d = true then + error("should not be reachable") + end + assert(c == nil) + return r +]], "ok") +test("several let in if condition, only test the first", [[ + if a = false then + error("condition was false") + elseif b = nil then + error("condition was nil") + elseif c, d = false, "ok" then + error("should have tested against c") + else + return d + end +]], "ok") +test("several let in if condition, evaluation order", [[ + local t = { k = "ok" } + if a = t[b,c = "k", "l"] then + assert(c == "l") + assert(b == "k") + return a + end +]], "ok") + +-- Method stub +test("method stub, basic", [[ + local t = { s = "ok", m = function(self) return self.s end } + local f = t:m + return f() +]], "ok") +test("method stub, store method", [[ + local t = { s = "ok", m = function(self) return self.s end } + local f = t:m + t.m = function() return "not ok" end + return f() +]], "ok") +test("method stub, store object", [[ + local t = { s = "ok", m = function(self) return self.s end } + local f = t:m + t = {} + return f() +]], "ok") +test("method stub, returns nil if method nil", [[ + local t = { m = nil } + return t:m +]], nil) + +-- Safe prefixes +test("safe method stub, when nil", [[ + return t?:m +]], nil) +test("safe method stub, when non-nil", [[ + local t = { s = "ok", m = function(self) return self.s end } + return t?:m() +]], "ok") + +test("safe call, when nil", [[ + return f?() +]], nil) +test("safe call, when non nil", [[ + f = function() return "ok" end + return f?() +]], "ok") + +test("safe index, when nil", [[ + return f?.l +]], nil) +test("safe index, when non nil", [[ + f = { l = "ok" } + return f?.l +]], "ok") + +test("safe prefixes, random chaining", [[ + f = { l = { m = function(s) return s or "ok" end } } + assert(f?.l?.m() == "ok") + assert(f?.l?.o == nil) + assert(f?.l?.o?() == nil) + assert(f?.lo?.o?() == nil) + assert(f?.l?:m?() == f.l) + assert(f?.l:mo == nil) + assert(f.l?:o?() == nil) +]]) + -- results local resultCounter = {} local testCounter = 0