From 91948109caa1cf08cf24ea068c968c9ff7bd5ac3 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 23 Aug 2019 19:50:49 +0200 Subject: [PATCH 01/52] Fixed using break and continue in the same loop, added vanilla Lua 5.1 target somehow I never encountered this before... well now there's more tests --- README.md | 10 +- candran.can | 14 +- candran.lua | 2796 ++++++++++------- compiler/lua51.can | 26 + compiler/lua53.can | 30 +- compiler/luajit.can | 2 + ....0-1.rockspec => candran-0.9.0-1.rockspec} | 4 +- test/test.lua | 94 +- 8 files changed, 1883 insertions(+), 1093 deletions(-) create mode 100644 compiler/lua51.can rename rockspec/{candran-0.8.0-1.rockspec => candran-0.9.0-1.rockspec} (96%) diff --git a/README.md b/README.md index 2b504b1..3634328 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Candran ======= -Candran is a dialect of the [Lua 5.3](http://www.lua.org) programming language which compiles to Lua 5.3 and Lua 5.1/LuaJit. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. +Candran is a dialect of the [Lua 5.3](http://www.lua.org) programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified. @@ -299,11 +299,11 @@ The preprocessor has access to the following variables : Compile targets --------------- -Candran is based on the Lua 5.3 syntax, but can be compiled to both Lua 5.3 and Lua 5.1/LuaJit. +Candran is based on the Lua 5.3 syntax, but can be compiled to Lua 5.3, LuaJIT, and Lua 5.1. -To chose a compile target, set the ```target``` option to ```lua53``` (default) or ```luajit``` in the option table when using the library or the command line tools. +To chose a compile target, set the ```target``` option to ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try detect the currently used Lua version and use it as a target by default. -Lua 5.3 specific syntax (bitwise operators, integer division) will automatically be translated in valid Lua 5.1 code, using LuaJIT's ```bit``` library if necessary. Unless you require LuaJIT's library, you won't be able to use bitwise operators with simple Lua 5.1 ("PUC Lua"). +For the ```luajit``` and ```lua51``` targets, Lua 5.3 specific syntax (bitwise operators, integer division) will automatically be translated to valid Lua 5.1 syntax, using LuaJIT's ```bit``` library if necessary. Unless you require LuaJIT's library, you won't be able to use bitwise operators with simple Lua 5.1 ("PUC Lua"). **Please note** that Candran only translates syntax, and will not try to do anything about changes in the Lua standard library (for example, the new utf8 module). If you need this, you should be able to use [lua-compat-5.3](https://github.com/keplerproject/lua-compat-5.3) along with Candran. @@ -439,7 +439,7 @@ at the top of your main Lua file. If a Candran file is found when you call ```re You can give arbitrary options which will be gived to the preprocessor, but Candran already provide and uses these with their associated default values: ```lua -target = "lua53" -- Compiler target. "lua53" or "luajit" (default is automatically selected based on the Lua version used). +target = "lua53" -- Compiler target. "lua53", "luajit" or "lua51" (default is automatically selected based on the Lua version used). indentation = "" -- Character(s) used for indentation in the compiled file. newline = "\n" -- Character(s) used for newlines in the compiled file. variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local variable to provide some functionality (example: to load LuaJIT's bit lib when using bitwise operators). diff --git a/candran.can b/candran.can index 83eeaba..b60384c 100644 --- a/candran.can +++ b/candran.can @@ -3,6 +3,7 @@ #import("compiler.lua53") #import("compiler.luajit") +#import("compiler.lua51") #import("lib.lua-parser.scope") #import("lib.lua-parser.validator") @@ -10,12 +11,12 @@ #import("lib.lua-parser.parser") local candran = { - VERSION = "0.8.0" + VERSION = "0.9.0" } --- Default options. candran.default = { - target = _VERSION == "Lua 5.1" and "luajit" or "lua53", + target = "lua53", indentation = "", newline = "\n", variablePrefix = "__CAN_", @@ -24,6 +25,15 @@ candran.default = { rewriteErrors = true } +-- Autodetect version +if _VERSION == "Lua 5.1" then + if package.loaded.jit then + candran.default.target = "luajit" + else + candran.default.target = "lua51" + end +end + --- Run the preprocessor -- @tparam input string input code -- @tparam options table arguments for the preprocessor. They will be inserted into the preprocessor environement. diff --git a/candran.lua b/candran.lua index ff8af30..24f8fdf 100644 --- a/candran.lua +++ b/candran.lua @@ -244,465 +244,471 @@ 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 -tags = setmetatable({ -- ./compiler/lua53.can:127 -["Block"] = function(t) -- ./compiler/lua53.can:129 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:130 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:131 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:132 -hasPush = false -- ./compiler/lua53.can:133 -end -- ./compiler/lua53.can:133 -local r = "" -- ./compiler/lua53.can:135 -if hasPush then -- ./compiler/lua53.can:136 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:137 -end -- ./compiler/lua53.can:137 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:139 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:140 -end -- ./compiler/lua53.can:140 -if t[# t] then -- ./compiler/lua53.can:142 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:143 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:125 +return "" -- ./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 newline() .. "::" .. var("continue") .. "::" -- ./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:143 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:145 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:146 +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 -return r -- ./compiler/lua53.can:148 -end, -- ./compiler/lua53.can:148 -["Do"] = function(t) -- ./compiler/lua53.can:154 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:155 -end, -- ./compiler/lua53.can:155 -["Set"] = function(t) -- ./compiler/lua53.can:158 -if # t == 2 then -- ./compiler/lua53.can:159 -return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:160 -elseif # t == 3 then -- ./compiler/lua53.can:161 -return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:162 -elseif # t == 4 then -- ./compiler/lua53.can:163 -if t[3] == "=" then -- ./compiler/lua53.can:164 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:165 -t[2], -- ./compiler/lua53.can:165 -t[1][1], -- ./compiler/lua53.can:165 -{ -- ./compiler/lua53.can:165 -["tag"] = "Paren", -- ./compiler/lua53.can:165 -t[4][1] -- ./compiler/lua53.can:165 -} -- ./compiler/lua53.can:165 -}, "Op") -- ./compiler/lua53.can:165 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:166 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:167 -t[2], -- ./compiler/lua53.can:167 -t[1][i], -- ./compiler/lua53.can:167 -{ -- ./compiler/lua53.can:167 -["tag"] = "Paren", -- ./compiler/lua53.can:167 -t[4][i] -- ./compiler/lua53.can:167 -} -- ./compiler/lua53.can:167 -}, "Op")) -- ./compiler/lua53.can:167 -end -- ./compiler/lua53.can:167 -return r -- ./compiler/lua53.can:169 -else -- ./compiler/lua53.can:169 +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 +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[3], -- ./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 -t[1][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[3], -- ./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 -t[1][i] -- ./compiler/lua53.can:173 +} -- ./compiler/lua53.can:173 }, "Op")) -- ./compiler/lua53.can:173 end -- ./compiler/lua53.can:173 return r -- ./compiler/lua53.can:175 -end -- ./compiler/lua53.can:175 else -- ./compiler/lua53.can:175 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:178 -t[2], -- ./compiler/lua53.can:178 -t[1][1], -- ./compiler/lua53.can:178 -{ -- ./compiler/lua53.can:178 -["tag"] = "Op", -- ./compiler/lua53.can:178 -t[4], -- ./compiler/lua53.can:178 -{ -- ./compiler/lua53.can:178 -["tag"] = "Paren", -- ./compiler/lua53.can:178 -t[5][1] -- ./compiler/lua53.can:178 -}, -- ./compiler/lua53.can:178 -t[1][1] -- ./compiler/lua53.can:178 -} -- ./compiler/lua53.can:178 -}, "Op") -- ./compiler/lua53.can:178 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:179 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:180 -t[2], -- ./compiler/lua53.can:180 -t[1][i], -- ./compiler/lua53.can:180 -{ -- ./compiler/lua53.can:180 -["tag"] = "Op", -- ./compiler/lua53.can:180 -t[4], -- ./compiler/lua53.can:180 -{ -- ./compiler/lua53.can:180 -["tag"] = "Paren", -- ./compiler/lua53.can:180 -t[5][i] -- ./compiler/lua53.can:180 -}, -- ./compiler/lua53.can:180 -t[1][i] -- ./compiler/lua53.can:180 -} -- ./compiler/lua53.can:180 -}, "Op")) -- ./compiler/lua53.can:180 -end -- ./compiler/lua53.can:180 -return r -- ./compiler/lua53.can:182 -end -- ./compiler/lua53.can:182 -end, -- ./compiler/lua53.can:182 -["While"] = function(t) -- ./compiler/lua53.can:186 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:187 -local r = "while " .. lua(t[1]) .. " do" .. indent() -- ./compiler/lua53.can:188 -if hasContinue then -- ./compiler/lua53.can:189 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:190 -end -- ./compiler/lua53.can:190 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:192 -if hasContinue then -- ./compiler/lua53.can:193 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:194 -end -- ./compiler/lua53.can:194 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:196 -return r -- ./compiler/lua53.can:197 -end, -- ./compiler/lua53.can:197 -["Repeat"] = function(t) -- ./compiler/lua53.can:200 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:201 -local r = "repeat" .. indent() -- ./compiler/lua53.can:202 -if hasContinue then -- ./compiler/lua53.can:203 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:204 -end -- ./compiler/lua53.can:204 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:206 -if hasContinue then -- ./compiler/lua53.can:207 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:208 -end -- ./compiler/lua53.can:208 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:210 -return r -- ./compiler/lua53.can:211 -end, -- ./compiler/lua53.can:211 -["If"] = function(t) -- ./compiler/lua53.can:214 -local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() -- ./compiler/lua53.can:215 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:216 -r = r .. ("elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -if # t % 2 == 1 then -- ./compiler/lua53.can:219 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:220 -end -- ./compiler/lua53.can:220 -return r .. "end" -- ./compiler/lua53.can:222 -end, -- ./compiler/lua53.can:222 -["Fornum"] = function(t) -- ./compiler/lua53.can:225 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:226 -if # t == 5 then -- ./compiler/lua53.can:227 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:228 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:229 -if hasContinue then -- ./compiler/lua53.can:230 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:231 -end -- ./compiler/lua53.can:231 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:233 -if hasContinue then -- ./compiler/lua53.can:234 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:235 -end -- ./compiler/lua53.can:235 -return r .. unindent() .. "end" -- ./compiler/lua53.can:237 -else -- ./compiler/lua53.can:237 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:239 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:240 -if hasContinue then -- ./compiler/lua53.can:241 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:242 -end -- ./compiler/lua53.can:242 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:244 -if hasContinue then -- ./compiler/lua53.can:245 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:246 -end -- ./compiler/lua53.can:246 -return r .. unindent() .. "end" -- ./compiler/lua53.can:248 +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 +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 +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 +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 -end, -- ./compiler/lua53.can:248 -["Forin"] = function(t) -- ./compiler/lua53.can:252 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:253 -local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:254 -if hasContinue then -- ./compiler/lua53.can:255 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:256 -end -- ./compiler/lua53.can:256 -r = r .. (lua(t[3])) -- ./compiler/lua53.can:258 -if hasContinue then -- ./compiler/lua53.can:259 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:260 -end -- ./compiler/lua53.can:260 -return r .. unindent() .. "end" -- ./compiler/lua53.can:262 -end, -- ./compiler/lua53.can:262 -["Local"] = function(t) -- ./compiler/lua53.can:265 -local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:266 -if t[2][1] then -- ./compiler/lua53.can:267 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:268 -end -- ./compiler/lua53.can:268 -return r -- ./compiler/lua53.can:270 -end, -- ./compiler/lua53.can:270 -["Let"] = function(t) -- ./compiler/lua53.can:273 -local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:274 -local r = "local " .. nameList -- ./compiler/lua53.can:275 -if t[2][1] then -- ./compiler/lua53.can:276 -if any(t[2], { -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Function", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Table", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Paren" -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -}) then -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:278 -else -- ./compiler/lua53.can:278 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:280 -end -- ./compiler/lua53.can:280 -end -- ./compiler/lua53.can:280 -return r -- ./compiler/lua53.can:283 -end, -- ./compiler/lua53.can:283 -["Localrec"] = function(t) -- ./compiler/lua53.can:286 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:287 -end, -- ./compiler/lua53.can:287 -["Goto"] = function(t) -- ./compiler/lua53.can:290 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:291 -end, -- ./compiler/lua53.can:291 -["Label"] = function(t) -- ./compiler/lua53.can:294 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:295 -end, -- ./compiler/lua53.can:295 -["Return"] = function(t) -- ./compiler/lua53.can:298 -local push = peek("push") -- ./compiler/lua53.can:299 -if push then -- ./compiler/lua53.can:300 -local r = "" -- ./compiler/lua53.can:301 -for _, val in ipairs(t) do -- ./compiler/lua53.can:302 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:303 -end -- ./compiler/lua53.can:303 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:305 -else -- ./compiler/lua53.can:305 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:307 -end -- ./compiler/lua53.can:307 -end, -- ./compiler/lua53.can:307 -["Push"] = function(t) -- ./compiler/lua53.can:311 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:312 -r = "" -- ./compiler/lua53.can:313 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:314 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:315 -end -- ./compiler/lua53.can:315 -if t[# t] then -- ./compiler/lua53.can:317 -if t[# t]["tag"] == "Call" or t[# t]["tag"] == "Invoke" then -- ./compiler/lua53.can:318 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:319 -else -- ./compiler/lua53.can:319 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:321 +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 +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 +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 -end -- ./compiler/lua53.can:321 -return r -- ./compiler/lua53.can:324 -end, -- ./compiler/lua53.can:324 -["Break"] = function() -- ./compiler/lua53.can:327 -return "break" -- ./compiler/lua53.can:328 -end, -- ./compiler/lua53.can:328 -["Continue"] = function() -- ./compiler/lua53.can:331 -return "break" -- ./compiler/lua53.can:332 -end, -- ./compiler/lua53.can:332 -["Nil"] = function() -- ./compiler/lua53.can:339 -return "nil" -- ./compiler/lua53.can:340 -end, -- ./compiler/lua53.can:340 -["Dots"] = function() -- ./compiler/lua53.can:343 -return "..." -- ./compiler/lua53.can:344 -end, -- ./compiler/lua53.can:344 -["Boolean"] = function(t) -- ./compiler/lua53.can:347 -return tostring(t[1]) -- ./compiler/lua53.can:348 -end, -- ./compiler/lua53.can:348 -["Number"] = function(t) -- ./compiler/lua53.can:351 -return tostring(t[1]) -- ./compiler/lua53.can:352 -end, -- ./compiler/lua53.can:352 -["String"] = function(t) -- ./compiler/lua53.can:355 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:356 -end, -- ./compiler/lua53.can:356 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:359 -local r = "(" -- ./compiler/lua53.can:360 -local decl = {} -- ./compiler/lua53.can:361 -if t[1][1] then -- ./compiler/lua53.can:362 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:363 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:364 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:365 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:366 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:367 -r = r .. (id) -- ./compiler/lua53.can:368 -else -- ./compiler/lua53.can:368 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:370 -end -- ./compiler/lua53.can:370 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:372 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:373 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:374 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:375 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:376 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:377 -r = r .. (", " .. id) -- ./compiler/lua53.can:378 -else -- ./compiler/lua53.can:378 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:384 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:385 -r = r .. (d .. newline()) -- ./compiler/lua53.can:386 +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 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:388 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:389 -end -- ./compiler/lua53.can:389 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:391 -if hasPush then -- ./compiler/lua53.can:392 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:393 -else -- ./compiler/lua53.can:393 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:395 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:395 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:397 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:398 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:399 -end -- ./compiler/lua53.can:399 -pop("push") -- ./compiler/lua53.can:401 -return r .. unindent() .. "end" -- ./compiler/lua53.can:402 -end, -- ./compiler/lua53.can:402 -["Function"] = function(t) -- ./compiler/lua53.can:404 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:405 -end, -- ./compiler/lua53.can:405 -["Pair"] = function(t) -- ./compiler/lua53.can:408 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:409 -end, -- ./compiler/lua53.can:409 -["Table"] = function(t) -- ./compiler/lua53.can:411 -if # t == 0 then -- ./compiler/lua53.can:412 -return "{}" -- ./compiler/lua53.can:413 -elseif # t == 1 then -- ./compiler/lua53.can:414 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:415 -else -- ./compiler/lua53.can:415 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:417 -end -- ./compiler/lua53.can:417 -end, -- ./compiler/lua53.can:417 -["TableCompr"] = function(t) -- ./compiler/lua53.can:421 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:422 -end, -- ./compiler/lua53.can:422 -["Op"] = function(t) -- ./compiler/lua53.can:425 -local r -- ./compiler/lua53.can:426 -if # t == 2 then -- ./compiler/lua53.can:427 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:428 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:429 -else -- ./compiler/lua53.can:429 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:431 -end -- ./compiler/lua53.can:431 -else -- ./compiler/lua53.can:431 +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 +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 = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:435 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:435 else -- ./compiler/lua53.can:435 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:437 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:437 end -- ./compiler/lua53.can:437 -end -- ./compiler/lua53.can:437 -return r -- ./compiler/lua53.can:440 -end, -- ./compiler/lua53.can:440 -["Paren"] = function(t) -- ./compiler/lua53.can:443 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:444 -end, -- ./compiler/lua53.can:444 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:451 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:452 -local r = "(function()" .. indent() -- ./compiler/lua53.can:453 -if hasPush then -- ./compiler/lua53.can:454 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:455 -else -- ./compiler/lua53.can:455 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:457 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:457 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:459 +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 +end, -- ./compiler/lua53.can:446 +["Paren"] = function(t) -- ./compiler/lua53.can:449 +return "(" .. lua(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 .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:461 -end -- ./compiler/lua53.can:461 -pop("push") -- ./compiler/lua53.can:463 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:464 -return r -- ./compiler/lua53.can:465 -end, -- ./compiler/lua53.can:465 -["DoExpr"] = function(t) -- ./compiler/lua53.can:468 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:469 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:470 -end -- ./compiler/lua53.can:470 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:472 -end, -- ./compiler/lua53.can:472 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:475 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:476 -end, -- ./compiler/lua53.can:476 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:479 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:480 -end, -- ./compiler/lua53.can:480 -["IfExpr"] = function(t) -- ./compiler/lua53.can:483 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:484 -local block = t[i] -- ./compiler/lua53.can:485 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:486 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:487 -end -- ./compiler/lua53.can:487 -end -- ./compiler/lua53.can:487 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:490 -end, -- ./compiler/lua53.can:490 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:493 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:494 -end, -- ./compiler/lua53.can:494 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:497 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:498 -end, -- ./compiler/lua53.can:498 -["Call"] = function(t) -- ./compiler/lua53.can:504 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:505 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:506 -else -- ./compiler/lua53.can:506 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:508 -end -- ./compiler/lua53.can:508 -end, -- ./compiler/lua53.can:508 -["Invoke"] = function(t) -- ./compiler/lua53.can:513 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:514 -return "(" .. lua(t[1]) .. "):" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:515 -else -- ./compiler/lua53.can:515 -return lua(t[1]) .. ":" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:517 -end -- ./compiler/lua53.can:517 -end, -- ./compiler/lua53.can:517 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:522 -if start == nil then start = 1 end -- ./compiler/lua53.can:522 -local r -- ./compiler/lua53.can:523 -if t[start] then -- ./compiler/lua53.can:524 -r = lua(t[start]) -- ./compiler/lua53.can:525 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:526 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:527 -end -- ./compiler/lua53.can:527 -else -- ./compiler/lua53.can:527 -r = "" -- ./compiler/lua53.can:530 -end -- ./compiler/lua53.can:530 -return r -- ./compiler/lua53.can:532 -end, -- ./compiler/lua53.can:532 -["Id"] = function(t) -- ./compiler/lua53.can:535 -return t[1] -- ./compiler/lua53.can:536 -end, -- ./compiler/lua53.can:536 -["Index"] = function(t) -- ./compiler/lua53.can:539 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:540 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:541 -else -- ./compiler/lua53.can:541 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:543 -end -- ./compiler/lua53.can:543 -end, -- ./compiler/lua53.can:543 -["_opid"] = { -- ./compiler/lua53.can:548 -["add"] = "+", -- ./compiler/lua53.can:549 -["sub"] = "-", -- ./compiler/lua53.can:549 -["mul"] = "*", -- ./compiler/lua53.can:549 -["div"] = "/", -- ./compiler/lua53.can:549 -["idiv"] = "//", -- ./compiler/lua53.can:550 -["mod"] = "%", -- ./compiler/lua53.can:550 -["pow"] = "^", -- ./compiler/lua53.can:550 -["concat"] = "..", -- ./compiler/lua53.can:550 -["band"] = "&", -- ./compiler/lua53.can:551 -["bor"] = "|", -- ./compiler/lua53.can:551 -["bxor"] = "~", -- ./compiler/lua53.can:551 -["shl"] = "<<", -- ./compiler/lua53.can:551 -["shr"] = ">>", -- ./compiler/lua53.can:551 -["eq"] = "==", -- ./compiler/lua53.can:552 -["ne"] = "~=", -- ./compiler/lua53.can:552 -["lt"] = "<", -- ./compiler/lua53.can:552 -["gt"] = ">", -- ./compiler/lua53.can:552 -["le"] = "<=", -- ./compiler/lua53.can:552 -["ge"] = ">=", -- ./compiler/lua53.can:552 -["and"] = "and", -- ./compiler/lua53.can:553 -["or"] = "or", -- ./compiler/lua53.can:553 -["unm"] = "-", -- ./compiler/lua53.can:553 -["len"] = "#", -- ./compiler/lua53.can:553 -["bnot"] = "~", -- ./compiler/lua53.can:553 -["not"] = "not" -- ./compiler/lua53.can:553 -} -- ./compiler/lua53.can:553 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:556 -error("don't know how to compile a " .. tostring(key) .. " to Lua 5.3") -- ./compiler/lua53.can:557 -end }) -- ./compiler/lua53.can:557 -local code = lua(ast) .. newline() -- ./compiler/lua53.can:563 -return requireStr .. code -- ./compiler/lua53.can:564 -end -- ./compiler/lua53.can:564 -end -- ./compiler/lua53.can:564 -local lua53 = _() or lua53 -- ./compiler/lua53.can:569 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:570 -local function _() -- ./compiler/lua53.can:573 -local function _() -- ./compiler/lua53.can:575 +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 +end -- ./compiler/lua53.can:493 +end -- ./compiler/lua53.can:493 +return lua(t, "_statexpr", "If") -- ./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 +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 @@ -815,457 +821,463 @@ 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 -tags = setmetatable({ -- ./compiler/lua53.can:127 -["Block"] = function(t) -- ./compiler/lua53.can:129 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:130 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:131 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:132 -hasPush = false -- ./compiler/lua53.can:133 -end -- ./compiler/lua53.can:133 -local r = "" -- ./compiler/lua53.can:135 -if hasPush then -- ./compiler/lua53.can:136 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:137 -end -- ./compiler/lua53.can:137 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:139 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:140 -end -- ./compiler/lua53.can:140 -if t[# t] then -- ./compiler/lua53.can:142 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:143 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:125 +return "" -- ./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 newline() .. "::" .. var("continue") .. "::" -- ./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:143 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:145 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:146 +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 -return r -- ./compiler/lua53.can:148 -end, -- ./compiler/lua53.can:148 -["Do"] = function(t) -- ./compiler/lua53.can:154 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:155 -end, -- ./compiler/lua53.can:155 -["Set"] = function(t) -- ./compiler/lua53.can:158 -if # t == 2 then -- ./compiler/lua53.can:159 -return lua(t[1], "_lhs") .. " = " .. lua(t[2], "_lhs") -- ./compiler/lua53.can:160 -elseif # t == 3 then -- ./compiler/lua53.can:161 -return lua(t[1], "_lhs") .. " = " .. lua(t[3], "_lhs") -- ./compiler/lua53.can:162 -elseif # t == 4 then -- ./compiler/lua53.can:163 -if t[3] == "=" then -- ./compiler/lua53.can:164 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:165 -t[2], -- ./compiler/lua53.can:165 -t[1][1], -- ./compiler/lua53.can:165 -{ -- ./compiler/lua53.can:165 -["tag"] = "Paren", -- ./compiler/lua53.can:165 -t[4][1] -- ./compiler/lua53.can:165 -} -- ./compiler/lua53.can:165 -}, "Op") -- ./compiler/lua53.can:165 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:166 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:167 -t[2], -- ./compiler/lua53.can:167 -t[1][i], -- ./compiler/lua53.can:167 -{ -- ./compiler/lua53.can:167 -["tag"] = "Paren", -- ./compiler/lua53.can:167 -t[4][i] -- ./compiler/lua53.can:167 -} -- ./compiler/lua53.can:167 -}, "Op")) -- ./compiler/lua53.can:167 -end -- ./compiler/lua53.can:167 -return r -- ./compiler/lua53.can:169 -else -- ./compiler/lua53.can:169 +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 +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[3], -- ./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 -t[1][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[3], -- ./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 -t[1][i] -- ./compiler/lua53.can:173 +} -- ./compiler/lua53.can:173 }, "Op")) -- ./compiler/lua53.can:173 end -- ./compiler/lua53.can:173 return r -- ./compiler/lua53.can:175 -end -- ./compiler/lua53.can:175 else -- ./compiler/lua53.can:175 -local r = lua(t[1], "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:178 -t[2], -- ./compiler/lua53.can:178 -t[1][1], -- ./compiler/lua53.can:178 -{ -- ./compiler/lua53.can:178 -["tag"] = "Op", -- ./compiler/lua53.can:178 -t[4], -- ./compiler/lua53.can:178 -{ -- ./compiler/lua53.can:178 -["tag"] = "Paren", -- ./compiler/lua53.can:178 -t[5][1] -- ./compiler/lua53.can:178 -}, -- ./compiler/lua53.can:178 -t[1][1] -- ./compiler/lua53.can:178 -} -- ./compiler/lua53.can:178 -}, "Op") -- ./compiler/lua53.can:178 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:179 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:180 -t[2], -- ./compiler/lua53.can:180 -t[1][i], -- ./compiler/lua53.can:180 -{ -- ./compiler/lua53.can:180 -["tag"] = "Op", -- ./compiler/lua53.can:180 -t[4], -- ./compiler/lua53.can:180 -{ -- ./compiler/lua53.can:180 -["tag"] = "Paren", -- ./compiler/lua53.can:180 -t[5][i] -- ./compiler/lua53.can:180 -}, -- ./compiler/lua53.can:180 -t[1][i] -- ./compiler/lua53.can:180 -} -- ./compiler/lua53.can:180 -}, "Op")) -- ./compiler/lua53.can:180 -end -- ./compiler/lua53.can:180 -return r -- ./compiler/lua53.can:182 -end -- ./compiler/lua53.can:182 -end, -- ./compiler/lua53.can:182 -["While"] = function(t) -- ./compiler/lua53.can:186 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:187 -local r = "while " .. lua(t[1]) .. " do" .. indent() -- ./compiler/lua53.can:188 -if hasContinue then -- ./compiler/lua53.can:189 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:190 -end -- ./compiler/lua53.can:190 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:192 -if hasContinue then -- ./compiler/lua53.can:193 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:194 -end -- ./compiler/lua53.can:194 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:196 -return r -- ./compiler/lua53.can:197 -end, -- ./compiler/lua53.can:197 -["Repeat"] = function(t) -- ./compiler/lua53.can:200 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:201 -local r = "repeat" .. indent() -- ./compiler/lua53.can:202 -if hasContinue then -- ./compiler/lua53.can:203 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:204 -end -- ./compiler/lua53.can:204 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:206 -if hasContinue then -- ./compiler/lua53.can:207 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:208 -end -- ./compiler/lua53.can:208 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:210 -return r -- ./compiler/lua53.can:211 -end, -- ./compiler/lua53.can:211 -["If"] = function(t) -- ./compiler/lua53.can:214 -local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent() -- ./compiler/lua53.can:215 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:216 -r = r .. ("elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -if # t % 2 == 1 then -- ./compiler/lua53.can:219 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:220 -end -- ./compiler/lua53.can:220 -return r .. "end" -- ./compiler/lua53.can:222 -end, -- ./compiler/lua53.can:222 -["Fornum"] = function(t) -- ./compiler/lua53.can:225 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:226 -if # t == 5 then -- ./compiler/lua53.can:227 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:228 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:229 -if hasContinue then -- ./compiler/lua53.can:230 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:231 -end -- ./compiler/lua53.can:231 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:233 -if hasContinue then -- ./compiler/lua53.can:234 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:235 -end -- ./compiler/lua53.can:235 -return r .. unindent() .. "end" -- ./compiler/lua53.can:237 -else -- ./compiler/lua53.can:237 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:239 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:240 -if hasContinue then -- ./compiler/lua53.can:241 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:242 -end -- ./compiler/lua53.can:242 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:244 -if hasContinue then -- ./compiler/lua53.can:245 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:246 -end -- ./compiler/lua53.can:246 -return r .. unindent() .. "end" -- ./compiler/lua53.can:248 +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 +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 +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 +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 -end, -- ./compiler/lua53.can:248 -["Forin"] = function(t) -- ./compiler/lua53.can:252 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:253 -local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:254 -if hasContinue then -- ./compiler/lua53.can:255 -r = r .. ("repeat" .. indent()) -- ./compiler/lua53.can:256 -end -- ./compiler/lua53.can:256 -r = r .. (lua(t[3])) -- ./compiler/lua53.can:258 -if hasContinue then -- ./compiler/lua53.can:259 -r = r .. (unindent() .. "until true") -- ./compiler/lua53.can:260 -end -- ./compiler/lua53.can:260 -return r .. unindent() .. "end" -- ./compiler/lua53.can:262 -end, -- ./compiler/lua53.can:262 -["Local"] = function(t) -- ./compiler/lua53.can:265 -local r = "local " .. lua(t[1], "_lhs") -- ./compiler/lua53.can:266 -if t[2][1] then -- ./compiler/lua53.can:267 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:268 -end -- ./compiler/lua53.can:268 -return r -- ./compiler/lua53.can:270 -end, -- ./compiler/lua53.can:270 -["Let"] = function(t) -- ./compiler/lua53.can:273 -local nameList = lua(t[1], "_lhs") -- ./compiler/lua53.can:274 -local r = "local " .. nameList -- ./compiler/lua53.can:275 -if t[2][1] then -- ./compiler/lua53.can:276 -if any(t[2], { -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Function", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Table", -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -"Paren" -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -}) then -- predeclaration doesn't matter otherwise -- ./compiler/lua53.can:277 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:278 -else -- ./compiler/lua53.can:278 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:280 -end -- ./compiler/lua53.can:280 -end -- ./compiler/lua53.can:280 -return r -- ./compiler/lua53.can:283 -end, -- ./compiler/lua53.can:283 -["Localrec"] = function(t) -- ./compiler/lua53.can:286 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:287 -end, -- ./compiler/lua53.can:287 -["Goto"] = function(t) -- ./compiler/lua53.can:290 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:291 -end, -- ./compiler/lua53.can:291 -["Label"] = function(t) -- ./compiler/lua53.can:294 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:295 -end, -- ./compiler/lua53.can:295 -["Return"] = function(t) -- ./compiler/lua53.can:298 -local push = peek("push") -- ./compiler/lua53.can:299 -if push then -- ./compiler/lua53.can:300 -local r = "" -- ./compiler/lua53.can:301 -for _, val in ipairs(t) do -- ./compiler/lua53.can:302 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:303 -end -- ./compiler/lua53.can:303 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:305 -else -- ./compiler/lua53.can:305 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:307 -end -- ./compiler/lua53.can:307 -end, -- ./compiler/lua53.can:307 -["Push"] = function(t) -- ./compiler/lua53.can:311 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:312 -r = "" -- ./compiler/lua53.can:313 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:314 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:315 -end -- ./compiler/lua53.can:315 -if t[# t] then -- ./compiler/lua53.can:317 -if t[# t]["tag"] == "Call" or t[# t]["tag"] == "Invoke" then -- ./compiler/lua53.can:318 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:319 -else -- ./compiler/lua53.can:319 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:321 +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 +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 +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 -end -- ./compiler/lua53.can:321 -return r -- ./compiler/lua53.can:324 -end, -- ./compiler/lua53.can:324 -["Break"] = function() -- ./compiler/lua53.can:327 -return "break" -- ./compiler/lua53.can:328 -end, -- ./compiler/lua53.can:328 -["Continue"] = function() -- ./compiler/lua53.can:331 -return "break" -- ./compiler/lua53.can:332 -end, -- ./compiler/lua53.can:332 -["Nil"] = function() -- ./compiler/lua53.can:339 -return "nil" -- ./compiler/lua53.can:340 -end, -- ./compiler/lua53.can:340 -["Dots"] = function() -- ./compiler/lua53.can:343 -return "..." -- ./compiler/lua53.can:344 -end, -- ./compiler/lua53.can:344 -["Boolean"] = function(t) -- ./compiler/lua53.can:347 -return tostring(t[1]) -- ./compiler/lua53.can:348 -end, -- ./compiler/lua53.can:348 -["Number"] = function(t) -- ./compiler/lua53.can:351 -return tostring(t[1]) -- ./compiler/lua53.can:352 -end, -- ./compiler/lua53.can:352 -["String"] = function(t) -- ./compiler/lua53.can:355 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:356 -end, -- ./compiler/lua53.can:356 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:359 -local r = "(" -- ./compiler/lua53.can:360 -local decl = {} -- ./compiler/lua53.can:361 -if t[1][1] then -- ./compiler/lua53.can:362 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:363 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:364 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:365 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:366 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:367 -r = r .. (id) -- ./compiler/lua53.can:368 -else -- ./compiler/lua53.can:368 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:370 -end -- ./compiler/lua53.can:370 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:372 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:373 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:374 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:375 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:376 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:377 -r = r .. (", " .. id) -- ./compiler/lua53.can:378 -else -- ./compiler/lua53.can:378 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -end -- ./compiler/lua53.can:380 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:384 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:385 -r = r .. (d .. newline()) -- ./compiler/lua53.can:386 +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 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:388 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:389 -end -- ./compiler/lua53.can:389 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:391 -if hasPush then -- ./compiler/lua53.can:392 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:393 -else -- ./compiler/lua53.can:393 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:395 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:395 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:397 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:398 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:399 -end -- ./compiler/lua53.can:399 -pop("push") -- ./compiler/lua53.can:401 -return r .. unindent() .. "end" -- ./compiler/lua53.can:402 -end, -- ./compiler/lua53.can:402 -["Function"] = function(t) -- ./compiler/lua53.can:404 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:405 -end, -- ./compiler/lua53.can:405 -["Pair"] = function(t) -- ./compiler/lua53.can:408 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:409 -end, -- ./compiler/lua53.can:409 -["Table"] = function(t) -- ./compiler/lua53.can:411 -if # t == 0 then -- ./compiler/lua53.can:412 -return "{}" -- ./compiler/lua53.can:413 -elseif # t == 1 then -- ./compiler/lua53.can:414 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:415 -else -- ./compiler/lua53.can:415 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:417 -end -- ./compiler/lua53.can:417 -end, -- ./compiler/lua53.can:417 -["TableCompr"] = function(t) -- ./compiler/lua53.can:421 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:422 -end, -- ./compiler/lua53.can:422 -["Op"] = function(t) -- ./compiler/lua53.can:425 -local r -- ./compiler/lua53.can:426 -if # t == 2 then -- ./compiler/lua53.can:427 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:428 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:429 -else -- ./compiler/lua53.can:429 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:431 -end -- ./compiler/lua53.can:431 -else -- ./compiler/lua53.can:431 +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 +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 = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:435 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:435 else -- ./compiler/lua53.can:435 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:437 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:437 end -- ./compiler/lua53.can:437 -end -- ./compiler/lua53.can:437 -return r -- ./compiler/lua53.can:440 -end, -- ./compiler/lua53.can:440 -["Paren"] = function(t) -- ./compiler/lua53.can:443 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:444 -end, -- ./compiler/lua53.can:444 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:451 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:452 -local r = "(function()" .. indent() -- ./compiler/lua53.can:453 -if hasPush then -- ./compiler/lua53.can:454 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:455 -else -- ./compiler/lua53.can:455 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:457 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:457 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:459 +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 +end, -- ./compiler/lua53.can:446 +["Paren"] = function(t) -- ./compiler/lua53.can:449 +return "(" .. lua(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 .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:461 -end -- ./compiler/lua53.can:461 -pop("push") -- ./compiler/lua53.can:463 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:464 -return r -- ./compiler/lua53.can:465 -end, -- ./compiler/lua53.can:465 -["DoExpr"] = function(t) -- ./compiler/lua53.can:468 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:469 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:470 -end -- ./compiler/lua53.can:470 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:472 -end, -- ./compiler/lua53.can:472 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:475 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:476 -end, -- ./compiler/lua53.can:476 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:479 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:480 -end, -- ./compiler/lua53.can:480 -["IfExpr"] = function(t) -- ./compiler/lua53.can:483 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:484 -local block = t[i] -- ./compiler/lua53.can:485 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:486 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:487 -end -- ./compiler/lua53.can:487 -end -- ./compiler/lua53.can:487 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:490 -end, -- ./compiler/lua53.can:490 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:493 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:494 -end, -- ./compiler/lua53.can:494 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:497 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:498 -end, -- ./compiler/lua53.can:498 -["Call"] = function(t) -- ./compiler/lua53.can:504 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:505 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:506 -else -- ./compiler/lua53.can:506 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:508 -end -- ./compiler/lua53.can:508 -end, -- ./compiler/lua53.can:508 -["Invoke"] = function(t) -- ./compiler/lua53.can:513 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:514 -return "(" .. lua(t[1]) .. "):" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:515 -else -- ./compiler/lua53.can:515 -return lua(t[1]) .. ":" .. lua(t[2], "Id") .. "(" .. lua(t, "_lhs", 3) .. ")" -- ./compiler/lua53.can:517 -end -- ./compiler/lua53.can:517 -end, -- ./compiler/lua53.can:517 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:522 -if start == nil then start = 1 end -- ./compiler/lua53.can:522 -local r -- ./compiler/lua53.can:523 -if t[start] then -- ./compiler/lua53.can:524 -r = lua(t[start]) -- ./compiler/lua53.can:525 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:526 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:527 -end -- ./compiler/lua53.can:527 -else -- ./compiler/lua53.can:527 -r = "" -- ./compiler/lua53.can:530 -end -- ./compiler/lua53.can:530 -return r -- ./compiler/lua53.can:532 -end, -- ./compiler/lua53.can:532 -["Id"] = function(t) -- ./compiler/lua53.can:535 -return t[1] -- ./compiler/lua53.can:536 -end, -- ./compiler/lua53.can:536 -["Index"] = function(t) -- ./compiler/lua53.can:539 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:540 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:541 -else -- ./compiler/lua53.can:541 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:543 -end -- ./compiler/lua53.can:543 -end, -- ./compiler/lua53.can:543 -["_opid"] = { -- ./compiler/lua53.can:548 -["add"] = "+", -- ./compiler/lua53.can:549 -["sub"] = "-", -- ./compiler/lua53.can:549 -["mul"] = "*", -- ./compiler/lua53.can:549 -["div"] = "/", -- ./compiler/lua53.can:549 -["idiv"] = "//", -- ./compiler/lua53.can:550 -["mod"] = "%", -- ./compiler/lua53.can:550 -["pow"] = "^", -- ./compiler/lua53.can:550 -["concat"] = "..", -- ./compiler/lua53.can:550 -["band"] = "&", -- ./compiler/lua53.can:551 -["bor"] = "|", -- ./compiler/lua53.can:551 -["bxor"] = "~", -- ./compiler/lua53.can:551 -["shl"] = "<<", -- ./compiler/lua53.can:551 -["shr"] = ">>", -- ./compiler/lua53.can:551 -["eq"] = "==", -- ./compiler/lua53.can:552 -["ne"] = "~=", -- ./compiler/lua53.can:552 -["lt"] = "<", -- ./compiler/lua53.can:552 -["gt"] = ">", -- ./compiler/lua53.can:552 -["le"] = "<=", -- ./compiler/lua53.can:552 -["ge"] = ">=", -- ./compiler/lua53.can:552 -["and"] = "and", -- ./compiler/lua53.can:553 -["or"] = "or", -- ./compiler/lua53.can:553 -["unm"] = "-", -- ./compiler/lua53.can:553 -["len"] = "#", -- ./compiler/lua53.can:553 -["bnot"] = "~", -- ./compiler/lua53.can:553 -["not"] = "not" -- ./compiler/lua53.can:553 -} -- ./compiler/lua53.can:553 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:556 -error("don't know how to compile a " .. tostring(key) .. " to Lua 5.3") -- ./compiler/lua53.can:557 -end }) -- ./compiler/lua53.can:557 +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 +end -- ./compiler/lua53.can:493 +end -- ./compiler/lua53.can:493 +return lua(t, "_statexpr", "If") -- ./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 +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 @@ -1299,16 +1311,651 @@ 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:563 -return requireStr .. code -- ./compiler/lua53.can:564 -end -- ./compiler/lua53.can:564 -end -- ./compiler/lua53.can:564 -local lua53 = _() or lua53 -- ./compiler/lua53.can:569 -return lua53 -- ./compiler/luajit.can:40 -end -- ./compiler/luajit.can:40 -local luajit = _() or luajit -- ./compiler/luajit.can:44 -package["loaded"]["compiler.luajit"] = luajit or true -- ./compiler/luajit.can:45 -local function _() -- ./compiler/luajit.can:49 +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 +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 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 +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 +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 +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 +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 "" -- ./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 newline() .. "::" .. var("continue") .. "::" -- ./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: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 +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 +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 +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 +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 +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 +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 +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 +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 +end, -- ./compiler/lua53.can:446 +["Paren"] = function(t) -- ./compiler/lua53.can:449 +return "(" .. lua(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 +end -- ./compiler/lua53.can:493 +end -- ./compiler/lua53.can:493 +return lua(t, "_statexpr", "If") -- ./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 +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 +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:26 +end -- ./compiler/lua51.can:26 +local lua51 = _() or lua51 -- ./compiler/lua51.can:30 +package["loaded"]["compiler.lua51"] = lua51 or true -- ./compiler/lua51.can:31 +local function _() -- ./compiler/lua51.can:35 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 @@ -2931,219 +3578,226 @@ 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 -local candran = { ["VERSION"] = "0.8.0" } -- candran.can:13 -candran["default"] = { -- candran.can:17 -["target"] = _VERSION == "Lua 5.1" and "luajit" or "lua53", -- candran.can:18 -["indentation"] = "", -- candran.can:19 +local candran = { ["VERSION"] = "0.9.0" } -- candran.can:14 +candran["default"] = { -- candran.can:18 +["target"] = "lua53", -- candran.can:19 +["indentation"] = "", -- candran.can:20 ["newline"] = "\ -", -- candran.can:20 -["variablePrefix"] = "__CAN_", -- candran.can:21 -["mapLines"] = true, -- candran.can:22 -["chunkname"] = "nil", -- candran.can:23 -["rewriteErrors"] = true -- candran.can:24 -} -- candran.can:24 -candran["preprocess"] = function(input, options) -- candran.can:31 -if options == nil then options = {} end -- candran.can:31 -options = util["merge"](candran["default"], options) -- candran.can:32 -local preprocessor = "" -- candran.can:35 -local i = 0 -- candran.can:36 -local inLongString = false -- candran.can:37 -local inComment = false -- candran.can:38 +", -- candran.can:21 +["variablePrefix"] = "__CAN_", -- candran.can:22 +["mapLines"] = true, -- candran.can:23 +["chunkname"] = "nil", -- candran.can:24 +["rewriteErrors"] = true -- candran.can:25 +} -- candran.can:25 +if _VERSION == "Lua 5.1" then -- candran.can:29 +if package["loaded"]["jit"] then -- candran.can:30 +candran["default"]["target"] = "luajit" -- candran.can:31 +else -- candran.can:31 +candran["default"]["target"] = "lua51" -- candran.can:33 +end -- candran.can:33 +end -- candran.can:33 +candran["preprocess"] = function(input, options) -- candran.can:41 +if options == nil then options = {} end -- candran.can:41 +options = util["merge"](candran["default"], options) -- candran.can:42 +local preprocessor = "" -- candran.can:45 +local i = 0 -- candran.can:46 +local inLongString = false -- candran.can:47 +local inComment = false -- candran.can:48 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:39 -i = i + (1) -- candran.can:40 -if inComment then -- candran.can:42 -inComment = not line:match("%]%]") -- candran.can:43 -elseif inLongString then -- candran.can:44 -inLongString = not line:match("%]%]") -- candran.can:45 -else -- candran.can:45 -if line:match("[^%-]%[%[") then -- candran.can:47 -inLongString = true -- candran.can:48 -elseif line:match("%-%-%[%[") then -- candran.can:49 -inComment = true -- candran.can:50 -end -- candran.can:50 -end -- candran.can:50 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- exclude shebang -- candran.can:53 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:54 -else -- candran.can:54 -local l = line:sub(1, - 2) -- candran.can:56 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:57 +)") do -- candran.can:49 +i = i + (1) -- candran.can:50 +if inComment then -- candran.can:52 +inComment = not line:match("%]%]") -- candran.can:53 +elseif inLongString then -- candran.can:54 +inLongString = not line:match("%]%]") -- candran.can:55 +else -- candran.can:55 +if line:match("[^%-]%[%[") then -- candran.can:57 +inLongString = true -- candran.can:58 +elseif line:match("%-%-%[%[") then -- candran.can:59 +inComment = true -- candran.can:60 +end -- candran.can:60 +end -- candran.can:60 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- exclude shebang -- candran.can:63 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:64 +else -- candran.can:64 +local l = line:sub(1, - 2) -- candran.can:66 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:67 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:58 -else -- candran.can:58 +") -- candran.can:68 +else -- candran.can:68 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:60 -end -- candran.can:60 -end -- candran.can:60 -end -- candran.can:60 -preprocessor = preprocessor .. ("return output") -- candran.can:64 -local env = util["merge"](_G, options) -- candran.can:67 -env["candran"] = candran -- candran.can:69 -env["output"] = "" -- candran.can:71 -env["import"] = function(modpath, margs) -- candran.can:78 -if margs == nil then margs = {} end -- candran.can:78 -local filepath = assert(util["search"](modpath), "No module named \"" .. modpath .. "\"") -- candran.can:79 -local f = io["open"](filepath) -- candran.can:82 -if not f then -- candran.can:83 -error("Can't open the module file to import") -- candran.can:83 -end -- candran.can:83 -margs = util["merge"](options, { -- candran.can:85 -["chunkname"] = filepath, -- candran.can:85 -["loadLocal"] = true, -- candran.can:85 -["loadPackage"] = true -- candran.can:85 -}, margs) -- candran.can:85 -local modcontent = candran["preprocess"](f:read("*a"), margs) -- candran.can:86 -f:close() -- candran.can:87 -local modname = modpath:match("[^%.]+$") -- candran.can:90 +") -- candran.can:70 +end -- candran.can:70 +end -- candran.can:70 +end -- candran.can:70 +preprocessor = preprocessor .. ("return output") -- candran.can:74 +local env = util["merge"](_G, options) -- candran.can:77 +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 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 +end -- candran.can:93 +margs = util["merge"](options, { -- candran.can:95 +["chunkname"] = filepath, -- candran.can:95 +["loadLocal"] = true, -- candran.can:95 +["loadPackage"] = true -- candran.can:95 +}, margs) -- candran.can:95 +local modcontent = candran["preprocess"](f:read("*a"), margs) -- candran.can:96 +f:close() -- candran.can:97 +local modname = modpath:match("[^%.]+$") -- candran.can:100 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:99 -end -- candran.can:99 -env["include"] = function(file) -- candran.can:104 -local f = io["open"](file) -- candran.can:105 -if not f then -- candran.can:106 -error("Can't open the file " .. file .. " to include") -- candran.can:106 -end -- candran.can:106 -env["write"](f:read("*a")) -- candran.can:107 -f:close() -- candran.can:108 -end -- candran.can:108 -env["write"] = function(...) -- candran.can:112 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:109 +end -- candran.can:109 +env["include"] = function(file) -- candran.can:114 +local f = io["open"](file) -- candran.can:115 +if not f then -- candran.can:116 +error("Can't open the file " .. file .. " to include") -- candran.can:116 +end -- candran.can:116 +env["write"](f:read("*a")) -- candran.can:117 +f:close() -- candran.can:118 +end -- candran.can:118 +env["write"] = function(...) -- candran.can:122 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:113 -end -- candran.can:113 -env["placeholder"] = function(name) -- candran.can:117 -if env[name] then -- candran.can:118 -env["write"](env[name]) -- candran.can:119 -end -- candran.can:119 -end -- candran.can:119 -local preprocess, err = util["load"](candran["compile"](preprocessor, args), "candran preprocessor", env) -- candran.can:124 -if not preprocess then -- candran.can:125 -error("Error while creating Candran preprocessor: " .. err) -- candran.can:125 -end -- candran.can:125 -local success, output = pcall(preprocess) -- candran.can:128 -if not success then -- candran.can:129 -error("Error while preprocessing file: " .. output) -- candran.can:129 +") -- candran.can:123 +end -- candran.can:123 +env["placeholder"] = function(name) -- candran.can:127 +if env[name] then -- candran.can:128 +env["write"](env[name]) -- candran.can:129 end -- candran.can:129 -return output -- candran.can:131 -end -- candran.can:131 -candran["compile"] = function(input, options) -- candran.can:138 -if options == nil then options = {} end -- candran.can:138 -options = util["merge"](candran["default"], options) -- candran.can:139 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:141 -if not ast then -- candran.can:143 -error("Compiler: error while parsing file: " .. errmsg) -- candran.can:144 -end -- candran.can:144 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:147 -end -- candran.can:147 -candran["make"] = function(code, options) -- candran.can:154 -return candran["compile"](candran["preprocess"](code, options), options) -- candran.can:155 -end -- candran.can:155 -local errorRewritingActive = false -- candran.can:158 -local codeCache = {} -- candran.can:159 -candran["loadfile"] = function(filepath, env, options) -- candran.can:162 -local f, err = io["open"](filepath) -- candran.can:163 -if not f then -- candran.can:164 -error("can't open the file: " .. err) -- candran.can:164 -end -- candran.can:164 -local content = f:read("*a") -- candran.can:165 -f:close() -- candran.can:166 -return candran["load"](content, filepath, env, options) -- candran.can:168 -end -- candran.can:168 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:173 -if options == nil then options = {} end -- candran.can:173 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:174 -codeCache[options["chunkname"]] = candran["make"](chunk, options) -- candran.can:176 -local f, err = util["load"](codeCache[options["chunkname"]], options["chunkname"], env) -- candran.can:177 -if f == nil then -- candran.can:182 -return f, "Candran unexpectedly generated invalid code: " .. err -- candran.can:183 -end -- candran.can:183 -if options["rewriteErrors"] == false then -- candran.can:186 -return f -- candran.can:187 -else -- candran.can:187 -return function(...) -- candran.can:189 -local params = { ... } -- candran.can:190 -if not errorRewritingActive then -- candran.can:191 -errorRewritingActive = true -- candran.can:192 -local t = { xpcall(function() -- candran.can:193 -return f(unpack(params)) -- candran.can:193 -end, candran["messageHandler"]) } -- candran.can:193 -errorRewritingActive = false -- candran.can:194 -if t[1] == false then -- candran.can:195 -error(t[2], 0) -- candran.can:196 -end -- candran.can:196 -return unpack(t, 2) -- candran.can:198 -else -- candran.can:198 -return f(...) -- candran.can:200 -end -- candran.can:200 -end -- candran.can:200 -end -- candran.can:200 -end -- candran.can:200 -candran["dofile"] = function(filename, options) -- candran.can:208 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:209 -if f == nil then -- candran.can:211 -error(err) -- candran.can:212 -else -- candran.can:212 -return f() -- candran.can:214 -end -- candran.can:214 -end -- candran.can:214 -candran["messageHandler"] = function(message) -- candran.can:220 +end -- candran.can:129 +local preprocess, err = util["load"](candran["compile"](preprocessor, args), "candran preprocessor", env) -- candran.can:134 +if not preprocess then -- candran.can:135 +error("Error while creating Candran preprocessor: " .. err) -- candran.can:135 +end -- candran.can:135 +local success, output = pcall(preprocess) -- candran.can:138 +if not success then -- candran.can:139 +error("Error while preprocessing file: " .. output) -- candran.can:139 +end -- candran.can:139 +return output -- candran.can:141 +end -- candran.can:141 +candran["compile"] = function(input, options) -- candran.can:148 +if options == nil then options = {} end -- candran.can:148 +options = util["merge"](candran["default"], options) -- candran.can:149 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:151 +if not ast then -- candran.can:153 +error("Compiler: error while parsing file: " .. errmsg) -- candran.can:154 +end -- candran.can:154 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:157 +end -- candran.can:157 +candran["make"] = function(code, options) -- candran.can:164 +return candran["compile"](candran["preprocess"](code, options), options) -- candran.can:165 +end -- candran.can:165 +local errorRewritingActive = false -- candran.can:168 +local codeCache = {} -- candran.can:169 +candran["loadfile"] = function(filepath, env, options) -- candran.can:172 +local f, err = io["open"](filepath) -- candran.can:173 +if not f then -- candran.can:174 +error("can't open the file: " .. err) -- candran.can:174 +end -- candran.can:174 +local content = f:read("*a") -- candran.can:175 +f:close() -- candran.can:176 +return candran["load"](content, filepath, env, options) -- candran.can:178 +end -- candran.can:178 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:183 +if options == nil then options = {} end -- candran.can:183 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:184 +codeCache[options["chunkname"]] = candran["make"](chunk, options) -- candran.can:186 +local f, err = util["load"](codeCache[options["chunkname"]], options["chunkname"], env) -- candran.can:187 +if f == nil then -- candran.can:192 +return f, "Candran unexpectedly generated invalid code: " .. err -- candran.can:193 +end -- candran.can:193 +if options["rewriteErrors"] == false then -- candran.can:196 +return f -- candran.can:197 +else -- candran.can:197 +return function(...) -- candran.can:199 +local params = { ... } -- candran.can:200 +if not errorRewritingActive then -- candran.can:201 +errorRewritingActive = true -- candran.can:202 +local t = { xpcall(function() -- candran.can:203 +return f(unpack(params)) -- candran.can:203 +end, candran["messageHandler"]) } -- candran.can:203 +errorRewritingActive = false -- candran.can:204 +if t[1] == false then -- candran.can:205 +error(t[2], 0) -- candran.can:206 +end -- candran.can:206 +return unpack(t, 2) -- candran.can:208 +else -- candran.can:208 +return f(...) -- candran.can:210 +end -- candran.can:210 +end -- candran.can:210 +end -- candran.can:210 +end -- candran.can:210 +candran["dofile"] = function(filename, options) -- candran.can:218 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:219 +if f == nil then -- candran.can:221 +error(err) -- candran.can:222 +else -- candran.can:222 +return f() -- candran.can:224 +end -- candran.can:224 +end -- candran.can:224 +candran["messageHandler"] = function(message) -- candran.can:230 return debug["traceback"](message, 2):gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:221 -line = tonumber(line) -- candran.can:222 -local originalFile -- candran.can:224 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:225 -if strName then -- candran.can:226 -if codeCache[strName] then -- candran.can:227 -originalFile = codeCache[strName] -- candran.can:228 -source = strName -- candran.can:229 -end -- candran.can:229 -else -- candran.can:229 -local fi = io["open"](source, "r") -- candran.can:232 -if fi then -- candran.can:233 -originalFile = fi:read("*a") -- candran.can:234 -fi:close() -- candran.can:235 -end -- candran.can:235 -end -- candran.can:235 -if originalFile then -- candran.can:239 -local i = 0 -- candran.can:240 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:231 +line = tonumber(line) -- candran.can:232 +local originalFile -- candran.can:234 +local strName = source:match("%[string \"(.-)\"%]") -- candran.can:235 +if strName then -- candran.can:236 +if codeCache[strName] then -- candran.can:237 +originalFile = codeCache[strName] -- candran.can:238 +source = strName -- candran.can:239 +end -- candran.can:239 +else -- candran.can:239 +local fi = io["open"](source, "r") -- candran.can:242 +if fi then -- candran.can:243 +originalFile = fi:read("*a") -- candran.can:244 +fi:close() -- candran.can:245 +end -- candran.can:245 +end -- candran.can:245 +if originalFile then -- candran.can:249 +local i = 0 -- candran.can:250 for l in originalFile:gmatch("([^\ -]*)") do -- candran.can:241 -i = i + 1 -- candran.can:242 -if i == line then -- candran.can:243 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:244 -if lineMap then -- candran.can:245 -if extSource ~= source then -- candran.can:246 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:247 -else -- candran.can:247 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:249 -end -- candran.can:249 -end -- candran.can:249 -break -- candran.can:252 -end -- candran.can:252 -end -- candran.can:252 -end -- candran.can:252 -end) -- candran.can:252 -end -- candran.can:252 -candran["searcher"] = function(modpath) -- candran.can:260 -local filepath = util["search"](modpath, { "can" }) -- candran.can:261 -if not filepath then -- candran.can:262 +]*)") do -- candran.can:251 +i = i + 1 -- candran.can:252 +if i == line then -- candran.can:253 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:254 +if lineMap then -- candran.can:255 +if extSource ~= source then -- candran.can:256 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:257 +else -- candran.can:257 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:259 +end -- candran.can:259 +end -- candran.can:259 +break -- candran.can:262 +end -- candran.can:262 +end -- candran.can:262 +end -- candran.can:262 +end) -- candran.can:262 +end -- candran.can:262 +candran["searcher"] = function(modpath) -- candran.can:270 +local filepath = util["search"](modpath, { "can" }) -- candran.can:271 +if not filepath then -- candran.can:272 return "\ -\9no candran file in package.path" -- candran.can:263 -end -- candran.can:263 -return candran["loadfile"](filepath) -- candran.can:265 -end -- candran.can:265 -candran["setup"] = function() -- candran.can:269 -if _VERSION == "Lua 5.1" then -- candran.can:270 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:271 -else -- candran.can:271 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:273 +\9no candran file in package.path" -- candran.can:273 end -- candran.can:273 -return candran -- candran.can:275 +return candran["loadfile"](filepath) -- candran.can:275 end -- candran.can:275 -return candran -- candran.can:278 +candran["setup"] = function() -- candran.can:279 +if _VERSION == "Lua 5.1" then -- candran.can:280 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:281 +else -- candran.can:281 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:283 +end -- candran.can:283 +return candran -- candran.can:285 +end -- candran.can:285 +return candran -- candran.can:288 diff --git a/compiler/lua51.can b/compiler/lua51.can new file mode 100644 index 0000000..9c4b8f5 --- /dev/null +++ b/compiler/lua51.can @@ -0,0 +1,26 @@ +states.continue = {} -- when in a loop that use continue + +CONTINUE_START = () + return "local " .. var("break") .. newline() .. "repeat" .. indent() .. push("continue", var("break")) +end +CONTINUE_STOP = () + return pop("continue") .. unindent() .. "until true" .. newline() .. "if " .. var("break") .. " then break end" +end + +tags.Continue = () + return "break" +end +tags.Break = () + local inContinue = peek("continue") + if inContinue then + return inContinue .. " = true" .. newline() .. "break" + else + return "break" + end +end + +#local patch = output +#output = "" +#import("compiler.luajit", { patch = patch, loadPackage = false }) + +return luajit diff --git a/compiler/lua53.can b/compiler/lua53.can index a27c49e..c838d44 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -122,6 +122,12 @@ return function(code, ast, options) 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" end + local CONTINUE_START = () -- at the start of loops using continue + return "" + end + local CONTINUE_STOP = () -- at the start of loops using continue + return newline() .. "::" .. var("continue") .. "::" + end --- Tag constructors tags = setmetatable({ @@ -187,25 +193,25 @@ return function(code, ast, options) local hasContinue = any(t[2], { "Continue" }, loop) local r = "while " .. lua(t[1]) .. " do" .. indent() if hasContinue then - r ..= "repeat" .. indent() + r ..= CONTINUE_START() end r .. = lua(t[2]) if hasContinue then - r ..= unindent() .. "until true" + r ..= CONTINUE_STOP() end r ..= unindent() .. "end" return r end, -- Repeat{ block expr } Repeat = (t) - local hasContinue = any(t[2], { "Continue" }, loop) + local hasContinue = any(t[1], { "Continue" }, loop) local r = "repeat" .. indent() if hasContinue then - r ..= "repeat" .. indent() + r ..= CONTINUE_START() end r .. = lua(t[1]) if hasContinue then - r ..= unindent() .. "until true" + r ..= CONTINUE_STOP() end r ..= unindent() .. "until " .. lua(t[2]) return r @@ -228,22 +234,22 @@ return function(code, ast, options) local hasContinue = any(t[5], { "Continue" }, loop) r ..= ", " .. lua(t[4]) .. " do" .. indent() if hasContinue then - r ..= "repeat" .. indent() + r ..= CONTINUE_START() end r ..= lua(t[5]) if hasContinue then - r ..= unindent() .. "until true" + r ..= CONTINUE_STOP() end return r .. unindent() .. "end" else local hasContinue = any(t[4], { "Continue" }, loop) r ..= " do" .. indent() if hasContinue then - r ..= "repeat" .. indent() + r ..= CONTINUE_START() end r ..= lua(t[4]) if hasContinue then - r ..= unindent() .. "until true" + r ..= CONTINUE_STOP() end return r .. unindent() .. "end" end @@ -253,11 +259,11 @@ return function(code, ast, options) local hasContinue = any(t[3], { "Continue" }, loop) local r = "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() if hasContinue then - r ..= "repeat" .. indent() + r ..= CONTINUE_START() end r ..= lua(t[3]) if hasContinue then - r ..= unindent() .. "until true" + r ..= CONTINUE_STOP() end return r .. unindent() .. "end" end, @@ -329,7 +335,7 @@ return function(code, ast, options) end, -- Continue Continue = () - return "break" + return "goto " .. var("continue") end, -- apply (below) diff --git a/compiler/luajit.can b/compiler/luajit.can index f0f7f2c..51a720f 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -33,6 +33,8 @@ tags._opid.bnot = (right) return var("bnot") .. "(" .. lua(right) .. ")" end +#placeholder("patch") + #local patch = output #output = "" #import("compiler.lua53", { patch = patch, loadPackage = false }) diff --git a/rockspec/candran-0.8.0-1.rockspec b/rockspec/candran-0.9.0-1.rockspec similarity index 96% rename from rockspec/candran-0.8.0-1.rockspec rename to rockspec/candran-0.9.0-1.rockspec index e1e83ad..6b7592e 100644 --- a/rockspec/candran-0.8.0-1.rockspec +++ b/rockspec/candran-0.9.0-1.rockspec @@ -2,7 +2,7 @@ rockspec_format = "3.0" package = "candran" -version = "0.8.0-1" +version = "0.9.0-1" description = { summary = "A simple Lua dialect and preprocessor.", @@ -19,7 +19,7 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.8.0" + tag = "v0.9.0" } dependencies = { diff --git a/test/test.lua b/test/test.lua index dba55a8..ce3a7bd 100644 --- a/test/test.lua +++ b/test/test.lua @@ -384,7 +384,61 @@ return a.foo() ]], "table") -- continue keyword -test("continue keyword", [[ +test("continue keyword in while", [[ +local a = "" +local i = 0 +while i < 10 do + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i +end +return a +]], "13579") +test("continue keyword in while, used with break", [[ +local a = "" +local i = 0 +while i < 10 do + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end +end +return a +]], "135") +test("continue keyword in repeat", [[ +local a = "" +local i = 0 +repeat + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i +until i == 10 +return a +]], "13579") +test("continue keyword in repeat, used with break", [[ +local a = "" +local i = 0 +repeat + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end +until i == 10 +return a +]], "135") +test("continue keyword in fornum", [[ local a = "" for i=1, 10 do if i % 2 == 0 then @@ -394,6 +448,44 @@ for i=1, 10 do end return a ]], "13579") +test("continue keyword in fornum, used with break", [[ +local a = "" +for i=1, 10 do + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end +end +return a +]], "135") +test("continue keyword in for", [[ +local t = {1,2,3,4,5,6,7,8,9,10} +local a = "" +for _, i in ipairs(t) do + if i % 2 == 0 then + continue + end + a = a .. i +end +return a +]], "13579") +test("continue keyword in for, used with break", [[ +local t = {1,2,3,4,5,6,7,8,9,10} +local a = "" +for _, i in ipairs(t) do + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end +end +return a +]], "135") -- push keyword test("push keyword", [[ From 7df95abc6db56fcf5caceabc0579b8b942381046 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 23 Aug 2019 21:12:45 +0200 Subject: [PATCH 02/52] Fixed using return at the end of a loop that use continue --- candran.lua | 28 +++++++++++++++++----------- compiler/lua51.can | 7 +++++++ compiler/lua53.can | 4 ++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/candran.lua b/candran.lua index 24f8fdf..82584c6 100644 --- a/candran.lua +++ b/candran.lua @@ -245,10 +245,10 @@ local APPEND = function(t, toAppend) -- append values "toAppend" (multiple value 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 "" -- ./compiler/lua53.can:126 +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 newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 tags = setmetatable({ -- ./compiler/lua53.can:133 ["Block"] = function(t) -- ./compiler/lua53.can:135 @@ -822,10 +822,10 @@ local APPEND = function(t, toAppend) -- append values "toAppend" (multiple value 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 "" -- ./compiler/lua53.can:126 +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 newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 tags = setmetatable({ -- ./compiler/lua53.can:133 ["Block"] = function(t) -- ./compiler/lua53.can:135 @@ -1436,10 +1436,10 @@ local APPEND = function(t, toAppend) -- append values "toAppend" (multiple value 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 "" -- ./compiler/lua53.can:126 +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 newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:129 end -- ./compiler/lua53.can:129 tags = setmetatable({ -- ./compiler/lua53.can:133 ["Block"] = function(t) -- ./compiler/lua53.can:135 @@ -1943,6 +1943,12 @@ 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 @@ -1951,11 +1957,11 @@ 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:26 -end -- ./compiler/lua51.can:26 -local lua51 = _() or lua51 -- ./compiler/lua51.can:30 -package["loaded"]["compiler.lua51"] = lua51 or true -- ./compiler/lua51.can:31 -local function _() -- ./compiler/lua51.can:35 +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 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 diff --git a/compiler/lua51.can b/compiler/lua51.can index 9c4b8f5..2af7629 100644 --- a/compiler/lua51.can +++ b/compiler/lua51.can @@ -19,6 +19,13 @@ 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 + #local patch = output #output = "" #import("compiler.luajit", { patch = patch, loadPackage = false }) diff --git a/compiler/lua53.can b/compiler/lua53.can index c838d44..3e1ae64 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -123,10 +123,10 @@ return function(code, ast, options) 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 "" + return "do" .. indent() end local CONTINUE_STOP = () -- at the start of loops using continue - return newline() .. "::" .. var("continue") .. "::" + return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" end --- Tag constructors From da4ee63f3f9b552f79e6b82d318d681e28773228 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 23 Aug 2019 23:16:52 +0200 Subject: [PATCH 03/52] Fixed line numbers in errors for Lua 5.1/LuaJIT, hopefully finally for some reason gmatch("[^\n]*") matches *two times* per line (one with the line, and an empty string) in Lua 5.1 and LuaJIT, but behave as expected in Lua 5.2/5.3... --- candran.can | 4 ++-- candran.lua | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/candran.can b/candran.can index b60384c..923e588 100644 --- a/candran.can +++ b/candran.can @@ -11,7 +11,7 @@ #import("lib.lua-parser.parser") local candran = { - VERSION = "0.9.0" + VERSION = "0.9.1" } --- Default options. @@ -248,7 +248,7 @@ function candran.messageHandler(message) if originalFile then local i = 0 - for l in originalFile:gmatch("([^\n]*)") do + for l in originalFile:gmatch("([^\n]*)\n") do i = i +1 if i == line then local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") diff --git a/candran.lua b/candran.lua index 82584c6..a7ea161 100644 --- a/candran.lua +++ b/candran.lua @@ -3584,7 +3584,7 @@ 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 -local candran = { ["VERSION"] = "0.9.0" } -- candran.can:14 +local candran = { ["VERSION"] = "0.9.1" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 ["indentation"] = "", -- candran.can:20 @@ -3773,7 +3773,8 @@ end -- candran.can:245 if originalFile then -- candran.can:249 local i = 0 -- candran.can:250 for l in originalFile:gmatch("([^\ -]*)") do -- candran.can:251 +]*)\ +") do -- candran.can:251 i = i + 1 -- candran.can:252 if i == line then -- candran.can:253 local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:254 From d410606dc0680d3074cd6e67fabfead0837b6941 Mon Sep 17 00:00:00 2001 From: Reuh Date: Sat, 24 Aug 2019 15:19:59 +0200 Subject: [PATCH 04/52] Readme cleanup --- README.md | 138 +++++++++++++++++++++++++++++------------------------- bin/can | 3 ++ bin/canc | 7 +-- 3 files changed, 80 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 3634328..9cdc00b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ Candran ======= -Candran is a dialect of the [Lua 5.3](http://www.lua.org) programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. +Candran is a dialect of the [Lua 5.3](http://www.lua.org) programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. -Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified. +Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. ````lua #import("lib.thing") -- static import @@ -25,7 +25,7 @@ let a = { end, selfReference = () -- short function declaration, without self - return a -- no need for a prior local declaration using let + return a -- no need for a prior local declaration when using let end } @@ -33,7 +33,7 @@ a:method(42, (foo) return "something " .. foo end) -local odd = [ -- table comprehension (kind of) +local odd = [ -- table comprehension for i=1, 10 do if i%2 == 0 then continue -- continue keyword @@ -46,10 +46,12 @@ local count = [for i=1,10 i] -- single line statements local a = if condition then "one" else "two" end -- statement as expressions -print("Hello %s":format("world")) -- methods calls on strings (and tables) litterals without enclosing parantheses +print("Hello %s":format("world")) -- methods calls on strings (and tables) litterals without enclosing parentheses ```` +**Current status**: Candran in heavily used in several of my personal projects and works as expected. + Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup @@ -91,9 +93,9 @@ For example, a ````var += nb```` assignment will be compiled into ````var = var All theses operators can also be put right of the assigment operator, in which case ```var =+ nb``` will be compiled into ```var = nb + var```. -If you feel like writing hard to understand code, right and left operator can be used at the same time. +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 good code, write spaced code: `a = -1` works as expected. +**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. ##### Default function parameters ```lua @@ -101,11 +103,11 @@ function foo(bar = "default", other = thing.do()) -- stuff end ``` -If an argument isn't provided or ```nil``` when the function is called, it will be automatically set to a default value. +If an argument isn't provided or set to ```nil``` when the function is called, it will automatically be set to its default value. It is equivalent to doing ```if arg == nil then arg = default end``` for each argument at the start of the function. -The default values can be complete Lua expressions, and will be evaluated each time the function is run. +The default values can be any Lua expression, which will be evaluated in the function's scope each time the default value end up being used. ##### Short anonymous function declaration ```lua @@ -119,7 +121,7 @@ end ``` Anonymous function (functions values) can be created in a more concise way by omitting the ```function``` keyword. -A ```:``` can prefix the parameters paranthesis to automatically add a ```self``` parameter. +A ```:``` can prefix the parameters parenthesis to automatically add a ```self``` parameter. ##### `@` self aliases ```lua @@ -177,9 +179,9 @@ push "hey" -- Does *not* work, because it is a valid Lua syntax for push("hey") Add one or more value to the returned value list. If you use a `return` afterwards, the pushed values will be placed *before* the `return` values, otherwise the function will only return what was pushed. -This keyword is mainly useful when used through implicit `push` with table comprehension and statement expressions. +In particular, this keyword is useful when used through implicit `push` with table comprehension and statement expressions. -**Please note** that, in order to stay compatible with vanilla Lua syntax, any `push` immediatly followed by a `"string expression"`, `{table expression}` or `(paranthesis)` will be interpreted as a function call. It's recommended to use the implicit `push` instead (when possible). +**Please note** that, in order to stay compatible with vanilla Lua syntax, any `push` immediatly followed by a `"string expression"`, `{table expression}` or `(parenthesis)` will be interpreted as a function call. It's recommended to use the implicit `push` when possible. ##### Implicit `push` ```lua @@ -197,7 +199,7 @@ local square = (x) x*x end -- function(x) return x*x end Any list of expressions placed *at the end of a block* will be converted into a `push` automatically. -**Please note** that this doesn't work with `v()` function calls, because these are already valid statements. Use `push v()` instead. +**Please note** that this doesn't work with `v()` function calls, because these are already valid statements. Use `push v()` in this case. ##### Table comprehension ```lua @@ -224,12 +226,12 @@ You can write *any* code you want between `[` and `]`, this code will be run as Values returned by the function will be inserted in the generated table in the order they were returned. This way, each time you `push` value(s), they will be added to the table. -The table generation function also have access to the `self` (or its alias `@`) variable, which is the table which is being created, so you can set arbitrary fields of the table. +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. ##### Suffixable string and table litterals ```lua -"some text":upper() -- same as ("some text"):upper() in Lua -"string".upper -- the actual string.upper function. "string"["upper"] also works. +"some text":upper() -- "SOME TEXT". Same as ("some text"):upper() in Lua. +"string".upper -- the string.upper function. "string"["upper"] also works. {thing = 3}.thing -- 3. Also works with tables! [for i=0,5 do i*i end][3] -- 9. And table comprehensions! @@ -238,7 +240,7 @@ The table generation function also have access to the `self` (or its alias `@`) someFunction"thing":upper() -- same as (someFunction("thing")):upper() (i.e., the way it would be parsed by Lua) ``` -String litterals, table litterals, and comprehensions can be suffixed with `:` method calls, `.` indexing, or `[` indexing, without needing to be enclosed in parantheses. +String litterals, table litterals, and comprehensions can be suffixed with `:` method calls, `.` indexing, or `[` indexing, without needing to be enclosed in parentheses. **Please note**, that "normal" functions calls have priority over this syntax, in order to maintain Lua compatibility. @@ -255,7 +257,7 @@ a, b, c = for i=1,2 do i end print(a, b, c) -- 1, 2, nil ``` -Candran allows to use `if`, `do`, `while`, `repeat` and `for` statements as expressions. Their content will be run as if they were run in a separate function which is immediatly run. +`if`, `do`, `while`, `repeat` and `for` statements can be used as expressions. Their content will be run as if they were run in a separate function which is immediatly run. ##### One line statements ```lua @@ -271,7 +273,9 @@ else -- "end" is always needed for else! end ``` -`if`, `elseif`, `for`, and `while` statements can be writtent without `do`, `then` or `end`, in which case they contain a single statement. +`if`, `elseif`, `for`, and `while` statements can be written without `do`, `then` or `end`, in which case they contain a single statement. + +**Please note** that an `end` is always required for `else` blocks. ### Preprocessor Before compiling, Candran's preprocessor is run. It execute every line starting with a _#_ (ignoring prefixing whitespace, long strings and comments) as Candran code. @@ -287,23 +291,25 @@ For example, Will output ````print("Bonjour")```` or ````print("Hello")```` depending of the "lang" argument passed to the preprocessor. -The preprocessor has access to the following variables : -* ````candran```` : the Candran library table. -* ````output```` : the current preprocessor output string. -* ````import(module[, [options])```` : a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: ```loadLocal``` (default ```true```): ```true``` to automatically load the module into a local variable (i.e. ```local thing = require("module.thing")```); ```loadPackage``` (default ```true```): ```true``` to automatically load the module into the loaded packages table (so it will be available for following ```require("module")``` calls). -* ````include(filename)```` : a function which copy the contents of the file _filename_ to the output. -* ````write(...)```` : write to the preprocessor output. For example, ````#print("hello()")```` will output ````hello()```` in the final file. -* ```placeholder(name)``` : if the variable _name_ is defined in the preprocessor environement, its content will be inserted here. -* ````...```` : each arguments passed to the preprocessor is directly available. +The preprocessor has access to the following variables: +* ````candran````: the Candran library table. +* ````output````: the current preprocessor output string. Can be redefined at any time. +* ````import(module[, [options])````: a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: ```loadLocal``` (default ```true```): ```true``` to automatically load the module into a local variable (i.e. ```local thing = require("module.thing")```); ```loadPackage``` (default ```true```): ```true``` to automatically load the module into the loaded packages table (so it will be available for following ```require("module")``` calls). +* ````include(filename)````: a function which copy the contents of the file _filename_ to the output. +* ````write(...)````: write to the preprocessor output. For example, ````#write("hello()")```` will output ````hello()```` in the final file. +* ```placeholder(name)```: if the variable _name_ is defined in the preprocessor environement, its content will be inserted here. +* ````...````: each arguments passed to the preprocessor is directly available in the environment. * and every standard Lua library. Compile targets --------------- -Candran is based on the Lua 5.3 syntax, but can be compiled to Lua 5.3, LuaJIT, and Lua 5.1. +Candran is based on the Lua 5.3 syntax, but can be compiled to Lua 5.3, LuaJIT, and Lua 5.1 compatible code. -To chose a compile target, set the ```target``` option to ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try detect the currently used Lua version and use it as a target by default. +To chose a compile target, set the ```target``` option to ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. -For the ```luajit``` and ```lua51``` targets, Lua 5.3 specific syntax (bitwise operators, integer division) will automatically be translated to valid Lua 5.1 syntax, using LuaJIT's ```bit``` library if necessary. Unless you require LuaJIT's library, you won't be able to use bitwise operators with simple Lua 5.1 ("PUC Lua"). +For the ```luajit``` and ```lua51``` targets, Lua 5.3 specific syntax (bitwise operators, integer division) will automatically be translated to valid Lua 5.1 syntax, using LuaJIT's ```bit``` library if necessary. Unless LuaJIT's bit library is installed, you won't be able to use bitwise operators with vanilla Lua 5.1 ("PUC Lua"). + +The ```lua51``` target does not support gotos and labels. **Please note** that Candran only translates syntax, and will not try to do anything about changes in the Lua standard library (for example, the new utf8 module). If you need this, you should be able to use [lua-compat-5.3](https://github.com/keplerproject/lua-compat-5.3) along with Candran. @@ -320,7 +326,7 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Preprocess and compile each _filename_ Candran files, and creates the assiociated ```.lua``` files in the same directories. - _options_ is of type ````-somearg -anotherarg thing=somestring other=5 ...````, which will generate a Lua table ```{ somearg = true, anotherarg = true, thing = "somestring", other = 5 }```. + _options_ is of type ````-somearg -anotherarg thing=somestring other=5````, which will generate a Lua table ```{ somearg = true, anotherarg = true, thing = "somestring", other = 5 }```. You can choose to use another directory where files should be written using the ```dest=destinationDirectory``` argument. @@ -336,7 +342,7 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Instead of providing filenames, you can use ```-``` to read from standard input. - * example uses : + * example uses: ````canc foo.can```` @@ -362,24 +368,24 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Preprocess, compile and run _filename_ using the options provided. - This will automatically register the Candran package searcher so required file will be compiled as they are needed. + This will automatically register the Candran package searcher, so required Candran modules will be compiled as they are needed. - This command will use error rewriting if enabled. + This command will use error rewriting unless explicitely enabled (by setting the `rewriteErrors=false` option). Instead of providing a filename, you can use ```-``` to read from standard input. ### Library usage -Candran can also be used as a Lua library. For example, +Candran can also be used as a Lua library: ````lua -local candran = require("candran") +local candran = require("candran") -- load Candran -local f = io.open("foo.can") +local f = io.open("foo.can") -- read the file foo.can local contents = f:read("*a") f:close() -local compiled = candran.make(contents, { lang = "fr" }) +local compiled = candran.make(contents, { debug = true }) -- compile foo.can with debug set to true -load(compiled)() +load(compiled)() -- execute! -- or simpler... candran.dofile("foo.can") @@ -388,20 +394,19 @@ candran.dofile("foo.can") candran.setup() local foo = require("foo") ```` -Will load Candran, read the file _foo.can_, compile its contents with the argument _lang_ set to _"fr"_, and then execute the result. -The table returned by _require("candran")_ gives you access to : +The table returned by _require("candran")_ gives you access to: -##### Compiler & preprocessor API -* ````candran.VERSION```` : Candran's version string. -* ````candran.preprocess(code[, options])```` : return the Candran code _code_, preprocessed with _options_ as options table. -* ````candran.compile(code[, options])```` : return the Candran code compiled to Lua with _options_ as the option table. -* ````candran.make(code[, options])```` : return the Candran code, preprocessed and compiled with _options_ as options table. +##### Compiler & preprocessor +* ````candran.VERSION````: Candran's version string (e.g. `"0.9.0"`). +* ````candran.preprocess(code[, options])````: return the Candran code _code_, preprocessed with the _options_ options table. +* ````candran.compile(code[, options])````: return the Candran code compiled to Lua with the _options_ option table. +* ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table. ##### Code loading helpers -* ```candran.loadfile(filepath, env, options)``` : Candran equivalent to the Lua 5.3's loadfile funtion. Will rewrite errors by default. -* ```candran.load(chunk, chunkname, env, options)``` : Candran equivalent to the Lua 5.3's load funtion. Will rewrite errors by default. -* ```candran.dofile(filepath, options)``` : Candran equivalent to the Lua 5.3's dofile funtion. Will rewrite errors by default. +* ```candran.loadfile(filepath, env, options)```: Candran equivalent to the Lua 5.3's loadfile funtion. Will rewrite errors by default. +* ```candran.load(chunk, chunkname, env, options)```: Candran equivalent to the Lua 5.3's load funtion. Will rewrite errors by default. +* ```candran.dofile(filepath, options)```: Candran equivalent to the Lua 5.3's dofile funtion. Will rewrite errors by default. #### Error rewriting When using the command-line tools or the code loading helpers, Candran will automatically setup error rewriting: because the code is reformated when @@ -420,11 +425,14 @@ If you are using the preprocessor ```import()``` function, the source Candran fi example.can:12(final.lua:5): attempt to call a nil value (global 'iWantAnError') ``` -* ```candran.messageHandler(message)``` : The error message handler used by Candran. Use it in xpcall to rewrite stacktraces to display Candran source file lines instead of compiled Lua lines. +You can perform error rewriting manually using: + +* ```candran.messageHandler(message)```: the error message handler used by Candran. Given `message` the Lua error string, returns full Candran traceback where soure files and lines are rewritten to their Candran source. You can use it as is in xpcall as a message handler. ##### Package searching helpers -Candran comes with a custom package searcher which will automatically find, preprocesses and compile ```.can``` files. If you want to use Candran in your project without worrying about -compiling the files, you can simply call +Candran comes with a custom package searcher which will automatically find, preprocesses and compile ```.can``` files. + +If you want to use Candran in your project without worrying about compiling the files, you can simply call ```lua require("candran").setup() @@ -432,38 +440,38 @@ require("candran").setup() at the top of your main Lua file. If a Candran file is found when you call ```require()```, it will be automatically compiled and loaded. If both a Lua and Candran file match a module name, the Candran file will be loaded. -* ```candran.searcher(modpath)``` : Candran package searcher function. Use the existing package.path. -* ```candran.setup()``` : Register the Candran package searcher, and return the `candran` table. +* ```candran.searcher(modpath)```: Candran package searcher function. Use the existing package.path. +* ```candran.setup()```: register the Candran package searcher, and return the `candran` table. ##### Available compiler & preprocessor options -You can give arbitrary options which will be gived to the preprocessor, but Candran already provide and uses these with their associated default values: +You can give arbitrary options to the compiler and preprocessor, but Candran already provide and uses these with their associated default values: ```lua -target = "lua53" -- Compiler target. "lua53", "luajit" or "lua51" (default is automatically selected based on the Lua version used). -indentation = "" -- Character(s) used for indentation in the compiled file. -newline = "\n" -- Character(s) used for newlines in the compiled file. +target = "lua53" -- compiler target. "lua53", "luajit" or "lua51" (default is automatically selected based on the Lua version used). +indentation = "" -- character(s) used for indentation in the compiled file. +newline = "\n" -- character(s) used for newlines in the compiled file. variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local variable to provide some functionality (example: to load LuaJIT's bit lib when using bitwise operators). -mapLines = true -- If true, compiled files will contain comments at the end of each line indicating the associated line and source file. Needed for error rewriting. -chunkname = "nil" -- The chunkname used when running code using the helper functions and writing the line origin comments. Candran will try to set it to the original filename if it knows it. -rewriteErrors = true -- True to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall(). +mapLines = true -- if true, compiled files will contain comments at the end of each line indicating the associated line and source file. Needed for error rewriting. +chunkname = "nil" -- the chunkname used when running code using the helper functions and writing the line origin comments. Candran will try to set it to the original filename if it knows it. +rewriteErrors = true -- true to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall(). ``` -You can change these values in the table `candran.default`. +You can change the defaults used for these variables in the table `candran.default`. -There are also a few function-specific options available, see the associated functions documentation for more information. +There are also a few function-specific options available, see the preprocessor functions documentation for more information. ### Compiling the library The Candran library itself is written is Candran, so you have to compile it with an already compiled Candran library. The compiled _candran.lua_ should include every Lua library needed to run it. You will still need to install LPegLabel. -This command will use the precompilled version of this repository (candran.lua) to compile _candran.can_ and write the result in _candran.lua_ : +This command will use the precompilled version of this repository (_candran.lua_) to compile _candran.can_ and write the result in _candran.lua_: ```` canc candran.can ```` -You can then run the tests on your build : +You can then run the tests on your build: ```` cd test diff --git a/bin/can b/bin/can index 4259708..24927ce 100644 --- a/bin/can +++ b/bin/can @@ -7,7 +7,10 @@ local args = cmdline(arg) if args.help or args.h then print("Candran "..candran.VERSION.." interpreter by Reuh") print("Usage: "..arg[0].." [options] filename") + print("Specify no options to start the REPL.") print("Use - instead of a filename to read from the standard input.") + print("Interpreter options:") + print(" -help or -h print this text") print("Default options:") for opt, val in pairs(candran.default) do if type(val) == "string" then val = val:gsub("\n", "\\n") end diff --git a/bin/canc b/bin/canc index 3795f50..cd0b7ef 100644 --- a/bin/canc +++ b/bin/canc @@ -4,7 +4,9 @@ local cmdline = require("lib.cmdline") local parse = require("lib.lua-parser.parser").parse local pp = require("lib.lua-parser.pp") -if #arg < 1 then +local args = cmdline(arg) + +if #arg < 1 or args.help or args.h then print("Candran "..candran.VERSION.." compiler by Reuh") print("Usage: "..arg[0].." [options] filenames...") print("Use - instead of filenames to read from the standard input. The output file will be named stdin.lua by default.") @@ -16,6 +18,7 @@ if #arg < 1 then print(" -compile only run the compiler") print(" -parse only parse the file and prints errors to stdout") print(" -ast (for debugging purposes) only parse the files and dump the AST to stdout") + print(" -help or -h print this text") print("Default options:") for opt, val in pairs(candran.default) do if type(val) == "string" then val = val:gsub("\n", "\\n") end @@ -24,8 +27,6 @@ if #arg < 1 then return end -local args = cmdline(arg) - if arg[#arg] == "-" then table.insert(args, io.stdin) end From 6be81267d20274b81728c8d655468be2edca5838 Mon Sep 17 00:00:00 2001 From: Reuh Date: Sat, 24 Aug 2019 17:15:33 +0200 Subject: [PATCH 05/52] Making the REPL great again --- README.md | 44 ++++--- bin/can | 119 ++++++++++++++++-- candran.can | 2 +- candran.lua | 2 +- ideas.txt | 23 +++- ...0-1.rockspec => candran-0.10.0-1.rockspec} | 10 +- rockspec/candran-scm-1.rockspec | 6 +- 7 files changed, 168 insertions(+), 38 deletions(-) rename rockspec/{candran-0.9.0-1.rockspec => candran-0.10.0-1.rockspec} (67%) diff --git a/README.md b/README.md index 9cdc00b..cf6868e 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing L local function calculate(toadd=25) -- default parameters local result = thing.do() result += toadd - #if debug then -- preprocessor conditionals - print("Did something") - #end + #if debug then -- preprocessor conditionals + print("Did something") + #end return result end @@ -50,14 +50,16 @@ print("Hello %s":format("world")) -- methods calls on strings (and tables) litte ```` -**Current status**: Candran in heavily used in several of my personal projects and works as expected. +**Current status**: Candran is heavily used in several of my personal projects and works as expected. Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup -Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.8.0-1.rockspec```. +Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.10.0-1.rockspec```. -Or manually install LPegLabel (```luarocks install LPegLabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. +Or manually install LPegLabel (```luarocks install lpeglabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. + +You can optionally install lua-linenoise (```luarocks install linenoise```) for an improved REPL. The rockspec does not install linenoise by default. You can register the Candran package searcher in your main Lua file (`require("candran").setup()`) and any subsequent `require` call in your project will automatically search for Candran modules. @@ -100,7 +102,7 @@ Right and left operator can be used at the same time. ##### Default function parameters ```lua function foo(bar = "default", other = thing.do()) - -- stuff + -- stuff end ``` If an argument isn't provided or set to ```nil``` when the function is called, it will automatically be set to its default value. @@ -328,11 +330,11 @@ The library can be used standalone through the ```canc``` and ```can``` utility: _options_ is of type ````-somearg -anotherarg thing=somestring other=5````, which will generate a Lua table ```{ somearg = true, anotherarg = true, thing = "somestring", other = 5 }```. - You can choose to use another directory where files should be written using the ```dest=destinationDirectory``` argument. + You can choose to use another directory where files should be written using the ```dest=destinationDirectory``` argument. - You can choose the output filename using ```out=filename```. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. + You can choose the output filename using ```out=filename```. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. - ```canc``` can write to the standard output instead of creating files using the ```-print``` argument. + ```canc``` can write to the standard output instead of creating files using the ```-print``` argument. You can choose to run only the preprocessor or compile using the ```-preprocess``` and ```-compile``` flags. @@ -342,31 +344,35 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Instead of providing filenames, you can use ```-``` to read from standard input. - * example uses: + Use the ```-h``` or ```-help``` option to display a short help text. - ````canc foo.can```` + Example uses: + + * ````canc foo.can```` preprocess and compile _foo.can_ and write the result in _foo.lua_. - ````canc indentation=" " foo.can```` + * ````canc indentation=" " foo.can```` preprocess and compile _foo.can_ with 2-space indentation (readable code!) and write the result in _foo.lua_. - ````canc foo.can -verbose -print | lua```` + * ````canc foo.can -verbose -print | lua```` preprocess _foo.can_ with _verbose_ set to _true_, compile it and execute it. - ````canc -parse foo.can```` + * ````canc -parse foo.can```` checks foo.can for syntaxic errors. * ```can``` - Start a simplisitic Candran REPL. + Start a simplisitic Candran REPL. + + If you want a better REPL (autocompletion, history, ability to move the cursor), install lua-linenoise: ```luarocks install linenoise```. * ````can [options] filename```` - Preprocess, compile and run _filename_ using the options provided. + Preprocess, compile and run _filename_ using the options provided. This will automatically register the Candran package searcher, so required Candran modules will be compiled as they are needed. @@ -374,6 +380,8 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Instead of providing a filename, you can use ```-``` to read from standard input. + Use the ```-h``` or ```-help``` option to display a short help text. + ### Library usage Candran can also be used as a Lua library: ````lua @@ -398,7 +406,7 @@ local foo = require("foo") The table returned by _require("candran")_ gives you access to: ##### Compiler & preprocessor -* ````candran.VERSION````: Candran's version string (e.g. `"0.9.0"`). +* ````candran.VERSION````: Candran's version string (e.g. `"0.10.0"`). * ````candran.preprocess(code[, options])````: return the Candran code _code_, preprocessed with the _options_ options table. * ````candran.compile(code[, options])````: return the Candran code compiled to Lua with the _options_ option table. * ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table. diff --git a/bin/can b/bin/can index 24927ce..c2987b4 100644 --- a/bin/can +++ b/bin/can @@ -19,6 +19,7 @@ if args.help or args.h then return end +-- stdin if arg[#arg] == "-" then local f, err = candran.load(io.read("*a"), "stdin", nil, args) if not f then @@ -26,21 +27,123 @@ if arg[#arg] == "-" then os.exit(1) end f() +-- file elseif #args >= 1 then candran.dofile(args[1], args) -else -- REPL - print("Candran " .. candran.VERSION) +-- REPL +else + -- Setup linenoise + local s, l = pcall(require, "linenoise") + if not s then -- pure Lua compatibility thingy + l = { + linenoise = function(prompt) + io.write(prompt) + local s, line = pcall(io.read) + if not s then + if line == "interrupted!" then + return nil + else + return nil, err + end + end + return line + end, + historyadd = function() end, + setcompletion = function() end, + sethints = function() end, + enableutf8 = function() end + } + end + local keywords = { + -- Lua + "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", + "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", + "until", "while", + -- Candran + "continue", "let", "push" + } + l.enableutf8() + l.setcompletion(function(comp, line) + local var = line:match("[a-zA-Z_][a-zA-Z_0-9]*$") + if var then + for _, k in ipairs(keywords) do + if k:match("^"..var) then + comp:add(line .. k:sub(#var+1)) + end + end + for k in pairs(_ENV) do + if k:match("^"..var) then + comp:add(line .. k:sub(#var+1)) + end + end + end + end) + l.sethints(function(line) + local var = line:match("[a-zA-Z_][a-zA-Z_0-9]*$") + if var then + for _, k in ipairs(keywords) do + if k:match("^"..var) then + return k:sub(#var+1), { color = 2, bold = true } + end + end + for k in pairs(_ENV) do + if k:match("^"..var) then + return k:sub(#var+1), { color = 2 } + end + end + end + end) + + -- Introduction + print("Candran " .. candran.VERSION .. ", targeting " .. candran.default.target) candran.setup() + + -- REPL loop + local multiline = false -- true if wait for another line + local buffer while true do - io.write("> ") - local line = io.read() - if line:match("^=") then - line = line:gsub("^=", "return tostring(") .. ")" + local line, err = l.linenoise(multiline and ">> " or "> ") + + -- exit + if not line then + if not err then + if multiline then + multiline = false + line = "" + else + return + end + else + error(err) + end end - local t = { pcall(candran.load, line, "stdin") } + -- history + if line:match("[^%s]") then + l.historyadd(line) + end + + -- multiline + if multiline then + buffer = buffer .. "\n" .. line + multiline = false + else + buffer = line + end + + -- print shortcut + if buffer:match("^=") then + buffer = buffer:gsub("^=", "return tostring(") .. ")" + end + + -- exec + local t = { pcall(candran.load, buffer, "stdin") } if t[1] == false then - print(t[2]) + if t[2]:match("expected '[end})]+' to close") then + multiline = true + else + print(t[2]) + end else t = { pcall(t[2]) } if t[1] == false then diff --git a/candran.can b/candran.can index 923e588..e3df888 100644 --- a/candran.can +++ b/candran.can @@ -11,7 +11,7 @@ #import("lib.lua-parser.parser") local candran = { - VERSION = "0.9.1" + VERSION = "0.10.0" } --- Default options. diff --git a/candran.lua b/candran.lua index a7ea161..4867f48 100644 --- a/candran.lua +++ b/candran.lua @@ -3584,7 +3584,7 @@ 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 -local candran = { ["VERSION"] = "0.9.1" } -- candran.can:14 +local candran = { ["VERSION"] = "0.10.0" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 ["indentation"] = "", -- candran.can:20 diff --git a/ideas.txt b/ideas.txt index 15d2be7..2a91999 100644 --- a/ideas.txt +++ b/ideas.txt @@ -24,7 +24,7 @@ Please note that the following ideas are just random though and won't be necessa Feel free to open issues about ideas you find useful or want to improve. Otherwise, I will only implements them when I really need them or am bored. -Actually, open issues for everything. I know of a couple persons using Candran but have no idea what they like and want with it. +Actually, open issues for everything. I've heard that a couple of people use Candran, but have no idea what they like and want with it. * class keyword class Thing(parents...) @@ -37,6 +37,7 @@ end local a = new Thing() -> (TODO: define how classes work. May even use ClassCommons) +Not very Lua-ey to impose how to make your classes? * try / except|catch / finally / else / other keywords try @@ -52,6 +53,8 @@ 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 @@ -69,9 +72,13 @@ Will need to define stuff for a lot of Lua libraries (see the work already done While we're talking about static analysis, what about forking luacheck into candrancheck? Or at least make the line mapping work. +Will require work. + * array slicing local b = a[3:5:1] +is it actually useful? even in python I rarely use it, apart from extracting a row or column for a matrix (and we don't have >1D arrays in Lua so...) + * Destructuring assignment local pos = { x = 5, y = 12 } @@ -85,12 +92,24 @@ local x, y $= pos And in implicit assignments: for i, {x, y} in ipairs(positions) do +Sounds useful, at least the key-value part. + * String interpolation Delimited by ``: `Hi, my name is ${@name}` -- -> "blaba" .. tostring(@name) Also allows multi-line with this maybe? +meh + * Other potential inspiration https://www.ruby-lang.org/fr/ -Well done, you're at the end of the file! +* 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/rockspec/candran-0.9.0-1.rockspec b/rockspec/candran-0.10.0-1.rockspec similarity index 67% rename from rockspec/candran-0.9.0-1.rockspec rename to rockspec/candran-0.10.0-1.rockspec index 6b7592e..31e9cf4 100644 --- a/rockspec/candran-0.9.0-1.rockspec +++ b/rockspec/candran-0.10.0-1.rockspec @@ -2,24 +2,24 @@ rockspec_format = "3.0" package = "candran" -version = "0.9.0-1" +version = "0.10.0-1" description = { summary = "A simple Lua dialect and preprocessor.", detailed = [[ - Candran is a dialect of the Lua 5.3 programming language which compiles to Lua 5.3 and Lua 5.1/LuaJit. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. - Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified. + Candran is a dialect of the Lua 5.3 programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. + Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. ]], license = "MIT", homepage = "https://github.com/Reuh/candran", issues_url = "https://github.com/Reuh/candran", maintainer = "Étienne 'Reuh' Fildadut ", - labels = {"lpeg", "commandline"} + labels = { "lpeg", "commandline" } } source = { url = "git://github.com/Reuh/candran", - tag = "v0.9.0" + tag = "v0.10.0" } dependencies = { diff --git a/rockspec/candran-scm-1.rockspec b/rockspec/candran-scm-1.rockspec index f3fa2f7..f12891e 100644 --- a/rockspec/candran-scm-1.rockspec +++ b/rockspec/candran-scm-1.rockspec @@ -7,14 +7,14 @@ version = "scm-1" description = { summary = "A simple Lua dialect and preprocessor.", detailed = [[ - Candran is a dialect of the Lua 5.3 programming language which compiles to Lua 5.3 and Lua 5.1/LuaJit. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. - Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified. + Candran is a dialect of the Lua 5.3 programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. + Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. ]], license = "MIT", homepage = "https://github.com/Reuh/candran", issues_url = "https://github.com/Reuh/candran", maintainer = "Étienne 'Reuh' Fildadut ", - labels = {"lpeg", "commandline"} + labels = { "lpeg", "commandline" } } source = { From 851e9f89d62969ebef1eedb5aa9ddde421855b71 Mon Sep 17 00:00:00 2001 From: Reuh Date: Tue, 27 Aug 2019 17:07:33 +0200 Subject: [PATCH 06/52] Added safe operators, if/while with assignement, method stubs --- README.md | 100 +- candran.can | 2 +- candran.lua | 5743 ++++++++++++++++++---------------- compiler/lua51.can | 11 +- compiler/lua53.can | 314 +- compiler/luajit.can | 2 + ideas.txt | 21 +- lib/lua-parser/parser.lua | 114 +- lib/lua-parser/validator.lua | 60 +- lib/util.can | 2 +- test/test.lua | 164 +- 11 files changed, 3688 insertions(+), 2845 deletions(-) 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 From 842536b56179f6c55a68030a84422cdbb168e293 Mon Sep 17 00:00:00 2001 From: Reuh Date: Wed, 15 Jan 2020 20:42:27 +0100 Subject: [PATCH 07/52] Add destructuring assignement --- README.md | 33 +- candran.can | 2 +- candran.lua | 5562 +++++++++-------- compiler/lua53.can | 218 +- compiler/luajit.can | 2 +- ideas.txt | 40 +- lib/lua-parser/parser.lua | 27 +- lib/lua-parser/validator.lua | 2 + ...0-1.rockspec => candran-0.11.0-1.rockspec} | 5 +- test/test.lua | 917 +-- 10 files changed, 3823 insertions(+), 2985 deletions(-) rename rockspec/{candran-0.10.0-1.rockspec => candran-0.11.0-1.rockspec} (94%) diff --git a/README.md b/README.md index 0fd8a75..a715320 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ end) a.child?:method?() -- safe navigation operator +local {hey, method} = a -- destructuring assignement + local odd = [ -- table comprehension for i=1, 10 do if i%2 == 0 then @@ -70,11 +72,11 @@ end Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup -Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.10.0-1.rockspec```. +Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.11.0-1.rockspec```. Or manually install LPegLabel (```luarocks install lpeglabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. -You can optionally install lua-linenoise (```luarocks install linenoise```) for an improved REPL. The rockspec does not install linenoise by default. +You can optionally install lua-linenoise (```luarocks install linenoise```, version 0.9 or above) for an improved REPL. The rockspec will install linenoise by default. You can register the Candran package searcher in your main Lua file (`require("candran").setup()`) and any subsequent `require` call in your project will automatically search for Candran modules. @@ -245,6 +247,33 @@ Values returned by the function will be inserted in the generated table in the o The table generation function also have access to the `self` variable (and its alias `@`), which is the table which is being created, so you can set any of the table's field. +##### Destructuring assignement +```lua +t = { x = 1, y = 2, z = 3 } + +{x, y, z} = t -- x, y, z = t.x, t.y, t.z + +{x = o} = t -- o = t.x + +{["x"] = o} = t -- o = t["x"] + +-- Also works with local, let, for ... in, if with assignement, +=, etc. +local {x, y} = t +let {x, y} = t +for i, {x, y} in ipairs{t} do end +if {x, y} = t then end +{x} += t -- x = x + t.x + +-- Works as expected with multiple assignement. +a, {x, y, z}, b = 1, t, 2 + +``` + +Destruturing assignement allows to quickly extract fields from a table into a variable. + +This is done by replacing the variable name in any assignement with a table literal, where every item is the name of the field and assigned variable. It is possible to use a different field name than the variable name by naming the table item (`fieldName = var` or `[fieldExpression] = var`). + + ##### Safe navigation operators ```lua a = nil diff --git a/candran.can b/candran.can index b1e7af0..049d4ef 100644 --- a/candran.can +++ b/candran.can @@ -11,7 +11,7 @@ #import("lib.lua-parser.parser") local candran = { - VERSION = "0.10.0" + VERSION = "0.11.0" } --- Default options. diff --git a/candran.lua b/candran.lua index 94bb82f..e6aae42 100644 --- a/candran.lua +++ b/candran.lua @@ -141,7 +141,7 @@ local r = options["newline"] .. string["rep"](options["indentation"], indentLeve 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+)\ +")):match(".*%-%- (.-)%:(%d+)\ ") -- ./compiler/lua53.can:17 if source and line then -- ./compiler/lua53.can:19 lastSource = source -- ./compiler/lua53.can:20 @@ -165,672 +165,826 @@ 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 +local states = { -- ./compiler/lua53.can:47 +["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 +["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +local function push(name, state) -- ./compiler/lua53.can:53 +table["insert"](states[name], state) -- ./compiler/lua53.can:54 +return "" -- ./compiler/lua53.can:55 +end -- ./compiler/lua53.can:55 +local function pop(name) -- ./compiler/lua53.can:58 +table["remove"](states[name]) -- ./compiler/lua53.can:59 +return "" -- ./compiler/lua53.can:60 +end -- ./compiler/lua53.can:60 +local function set(name, state) -- ./compiler/lua53.can:63 +states[name][# states[name]] = state -- ./compiler/lua53.can:64 +return "" -- ./compiler/lua53.can:65 +end -- ./compiler/lua53.can:65 +local function peek(name) -- ./compiler/lua53.can:68 +return states[name][# states[name]] -- ./compiler/lua53.can:69 +end -- ./compiler/lua53.can:69 +local function var(name) -- ./compiler/lua53.can:74 +return options["variablePrefix"] .. name -- ./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 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 +local function tmp() -- ./compiler/lua53.can:79 +local scope = peek("scope") -- ./compiler/lua53.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 +table["insert"](scope, var) -- ./compiler/lua53.can:82 +return var -- ./compiler/lua53.can:83 +end -- ./compiler/lua53.can:83 +local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local requireStr = "" -- ./compiler/lua53.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 +if not required[req] then -- ./compiler/lua53.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 +required[req] = true -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 +local tagsCheck = {} -- ./compiler/lua53.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 +tagsCheck[tag] = true -- ./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 +local nofollowCheck = {} -- ./compiler/lua53.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 +nofollowCheck[tag] = true -- ./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 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 -end -- ./compiler/lua53.can:129 -return true -- ./compiler/lua53.can:132 +for _, node in ipairs(list) do -- ./compiler/lua53.can:113 +if type(node) == "table" then -- ./compiler/lua53.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 +return node -- ./compiler/lua53.can:116 +end -- ./compiler/lua53.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 +if r then -- ./compiler/lua53.can:120 +return r -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +return nil -- ./compiler/lua53.can:124 +end -- ./compiler/lua53.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 +local tagsCheck = {} -- ./compiler/lua53.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 +tagsCheck[tag] = 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 +local nofollowCheck = {} -- ./compiler/lua53.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 +nofollowCheck[tag] = true -- ./compiler/lua53.can:136 +end -- ./compiler/lua53.can:136 +local found = {} -- ./compiler/lua53.can:138 +for _, node in ipairs(list) do -- ./compiler/lua53.can:139 +if type(node) == "table" then -- ./compiler/lua53.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 +table["insert"](found, n) -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -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 -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 -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:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 +table["insert"](found, node) -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +return found -- ./compiler/lua53.can:151 +end -- ./compiler/lua53.can:151 +local function all(list, tags) -- ./compiler/lua53.can:155 +for _, node in ipairs(list) do -- ./compiler/lua53.can:156 +local ok = false -- ./compiler/lua53.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 +if node["tag"] == tag then -- ./compiler/lua53.can:159 +ok = true -- ./compiler/lua53.can:160 +break -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +if not ok then -- ./compiler/lua53.can:164 +return false -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +return true -- ./compiler/lua53.can:168 +end -- ./compiler/lua53.can:168 +local tags -- ./compiler/lua53.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 +lastInputPos = ast["pos"] -- ./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 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 +end -- ./compiler/lua53.can:178 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 +end -- ./compiler/lua53.can:183 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -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 -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 -- ./compiler/lua53.can:228 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +return "do" .. indent() -- ./compiler/lua53.can:189 +end -- ./compiler/lua53.can:189 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 +end -- ./compiler/lua53.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local vars = {} -- ./compiler/lua53.can:195 +local values = {} -- ./compiler/lua53.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 +for _, v in ipairs(list) do -- ./compiler/lua53.can:198 +local var, val -- ./compiler/lua53.can:199 +if v["tag"] == "Id" then -- ./compiler/lua53.can:200 +var = v -- ./compiler/lua53.can:201 +val = { -- ./compiler/lua53.can:202 +["tag"] = "Index", -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "Id", -- ./compiler/lua53.can:202 +list["id"] -- ./compiler/lua53.can:202 +}, -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "String", -- ./compiler/lua53.can:202 +v[1] -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 +var = v[2] -- ./compiler/lua53.can:204 +val = { -- ./compiler/lua53.can:205 +["tag"] = "Index", -- ./compiler/lua53.can:205 +{ -- ./compiler/lua53.can:205 +["tag"] = "Id", -- ./compiler/lua53.can:205 +list["id"] -- ./compiler/lua53.can:205 +}, -- ./compiler/lua53.can:205 +v[1] -- ./compiler/lua53.can:205 +} -- ./compiler/lua53.can:205 +else -- ./compiler/lua53.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 +end -- ./compiler/lua53.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 +val = { -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["rightOp"], -- ./compiler/lua53.can:210 +var, -- ./compiler/lua53.can:210 +{ -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["leftOp"], -- ./compiler/lua53.can:210 +val, -- ./compiler/lua53.can:210 +var -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 +val = { -- ./compiler/lua53.can:212 +["tag"] = "Op", -- ./compiler/lua53.can:212 +destructured["rightOp"], -- ./compiler/lua53.can:212 +var, -- ./compiler/lua53.can:212 +val -- ./compiler/lua53.can:212 +} -- ./compiler/lua53.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 +val = { -- ./compiler/lua53.can:214 +["tag"] = "Op", -- ./compiler/lua53.can:214 +destructured["leftOp"], -- ./compiler/lua53.can:214 +val, -- ./compiler/lua53.can:214 +var -- ./compiler/lua53.can:214 +} -- ./compiler/lua53.can:214 +end -- ./compiler/lua53.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +if # vars > 0 then -- ./compiler/lua53.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 +if newlineAfter then -- ./compiler/lua53.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 +else -- ./compiler/lua53.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 +end -- ./compiler/lua53.can:225 +else -- ./compiler/lua53.can:225 +return "" -- ./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:228 +tags = setmetatable({ -- ./compiler/lua53.can:233 +["Block"] = function(t) -- ./compiler/lua53.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 +hasPush = false -- ./compiler/lua53.can:239 +end -- ./compiler/lua53.can:239 +local r = push("scope", {}) -- ./compiler/lua53.can:241 +if hasPush then -- ./compiler/lua53.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 +end -- ./compiler/lua53.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 +r = r .. (lua(t[i]) .. 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 -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 -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 +if t[# t] then -- ./compiler/lua53.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 +end -- ./compiler/lua53.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 +end -- ./compiler/lua53.can:252 +return r .. pop("scope") -- ./compiler/lua53.can:254 +end, -- ./compiler/lua53.can:254 +["Do"] = function(t) -- ./compiler/lua53.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 +end, -- ./compiler/lua53.can:261 +["Set"] = function(t) -- ./compiler/lua53.can:264 +local expr = t[# t] -- ./compiler/lua53.can:266 +local vars, values = {}, {} -- ./compiler/lua53.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 +else -- ./compiler/lua53.can:272 +table["insert"](vars, n) -- ./compiler/lua53.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 +local r = "" -- ./compiler/lua53.can:280 +if # vars > 0 then -- ./compiler/lua53.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 +end -- ./compiler/lua53.can:282 +if # destructuringVars > 0 then -- ./compiler/lua53.can:284 +local destructured = {} -- ./compiler/lua53.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 +end -- ./compiler/lua53.can:287 +return r -- ./compiler/lua53.can:289 +elseif # t == 4 then -- ./compiler/lua53.can:290 +if t[3] == "=" then -- ./compiler/lua53.can:291 +local r = "" -- ./compiler/lua53.can:292 +if # vars > 0 then -- ./compiler/lua53.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 +t[2], -- ./compiler/lua53.can:294 +vars[1], -- ./compiler/lua53.can:294 +{ -- ./compiler/lua53.can:294 +["tag"] = "Paren", -- ./compiler/lua53.can:294 +values[1] -- ./compiler/lua53.can:294 +} -- ./compiler/lua53.can:294 +}, "Op")) -- ./compiler/lua53.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 +t[2], -- ./compiler/lua53.can:296 +vars[i], -- ./compiler/lua53.can:296 +{ -- ./compiler/lua53.can:296 +["tag"] = "Paren", -- ./compiler/lua53.can:296 +values[i] -- ./compiler/lua53.can:296 +} -- ./compiler/lua53.can:296 +}, "Op")) -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +if # destructuringVars > 0 then -- ./compiler/lua53.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./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 +return r -- ./compiler/lua53.can:304 +else -- ./compiler/lua53.can:304 +local r = "" -- ./compiler/lua53.can:306 +if # vars > 0 then -- ./compiler/lua53.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 +t[3], -- ./compiler/lua53.can:308 +{ -- ./compiler/lua53.can:308 +["tag"] = "Paren", -- ./compiler/lua53.can:308 +values[1] -- ./compiler/lua53.can:308 +}, -- ./compiler/lua53.can:308 +vars[1] -- ./compiler/lua53.can:308 +}, "Op")) -- ./compiler/lua53.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 +t[3], -- ./compiler/lua53.can:310 +{ -- ./compiler/lua53.can:310 +["tag"] = "Paren", -- ./compiler/lua53.can:310 +values[i] -- ./compiler/lua53.can:310 +}, -- ./compiler/lua53.can:310 +vars[i] -- ./compiler/lua53.can:310 +}, "Op")) -- ./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:310 +if # destructuringVars > 0 then -- ./compiler/lua53.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 +end -- ./compiler/lua53.can:316 +return r -- ./compiler/lua53.can:318 +end -- ./compiler/lua53.can:318 +else -- ./compiler/lua53.can:318 +local r = "" -- ./compiler/lua53.can:321 +if # vars > 0 then -- ./compiler/lua53.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 +t[2], -- ./compiler/lua53.can:323 +vars[1], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Op", -- ./compiler/lua53.can:323 +t[4], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Paren", -- ./compiler/lua53.can:323 +values[1] -- ./compiler/lua53.can:323 +}, -- ./compiler/lua53.can:323 +vars[1] -- ./compiler/lua53.can:323 +} -- ./compiler/lua53.can:323 +}, "Op")) -- ./compiler/lua53.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 +t[2], -- ./compiler/lua53.can:325 +vars[i], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Op", -- ./compiler/lua53.can:325 +t[4], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Paren", -- ./compiler/lua53.can:325 +values[i] -- ./compiler/lua53.can:325 +}, -- ./compiler/lua53.can:325 +vars[i] -- ./compiler/lua53.can:325 +} -- ./compiler/lua53.can:325 +}, "Op")) -- ./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 -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 -["String"] = function(t) -- ./compiler/lua53.can:449 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 -end, -- ./compiler/lua53.can:450 -["_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 -pop("push") -- ./compiler/lua53.can:495 -return r .. unindent() .. "end" -- ./compiler/lua53.can:496 -end, -- ./compiler/lua53.can:496 -["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 -["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:325 +if # destructuringVars > 0 then -- ./compiler/lua53.can:328 +local destructured = { -- ./compiler/lua53.can:329 +["rightOp"] = t[2], -- ./compiler/lua53.can:329 +["leftOp"] = t[4] -- ./compiler/lua53.can:329 +} -- ./compiler/lua53.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 +end -- ./compiler/lua53.can:331 +return r -- ./compiler/lua53.can:333 +end -- ./compiler/lua53.can:333 +end, -- ./compiler/lua53.can:333 +["While"] = function(t) -- ./compiler/lua53.can:337 +local r = "" -- ./compiler/lua53.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 +if # lets > 0 then -- ./compiler/lua53.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 +if # lets > 0 then -- ./compiler/lua53.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 +end -- ./compiler/lua53.can:349 +if hasContinue then -- ./compiler/lua53.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 +end -- ./compiler/lua53.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 +if hasContinue then -- ./compiler/lua53.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 +end -- ./compiler/lua53.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 +if # lets > 0 then -- ./compiler/lua53.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 +end -- ./compiler/lua53.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 +end -- ./compiler/lua53.can:363 +return r -- ./compiler/lua53.can:365 +end, -- ./compiler/lua53.can:365 +["Repeat"] = function(t) -- ./compiler/lua53.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 +local r = "repeat" .. indent() -- ./compiler/lua53.can:370 +if hasContinue then -- ./compiler/lua53.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 +end -- ./compiler/lua53.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 +if hasContinue then -- ./compiler/lua53.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 +end -- ./compiler/lua53.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 +return r -- ./compiler/lua53.can:379 +end, -- ./compiler/lua53.can:379 +["If"] = function(t) -- ./compiler/lua53.can:382 +local r = "" -- ./compiler/lua53.can:383 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 +if # lets > 0 then -- ./compiler/lua53.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 +toClose = toClose + (1) -- ./compiler/lua53.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 +if # lets > 0 then -- ./compiler/lua53.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 +toClose = toClose + (1) -- ./compiler/lua53.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 +end -- ./compiler/lua53.can:400 +else -- ./compiler/lua53.can:400 +r = r .. ("else") -- ./compiler/lua53.can:403 +end -- ./compiler/lua53.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 +end -- ./compiler/lua53.can:405 +if # t % 2 == 1 then -- ./compiler/lua53.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 +end -- ./compiler/lua53.can:408 +r = r .. ("end") -- ./compiler/lua53.can:410 +for i = 1, toClose do -- ./compiler/lua53.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 +end -- ./compiler/lua53.can:412 +return r -- ./compiler/lua53.can:414 +end, -- ./compiler/lua53.can:414 +["Fornum"] = function(t) -- ./compiler/lua53.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 +if # t == 5 then -- ./compiler/lua53.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 +if hasContinue then -- ./compiler/lua53.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 +end -- ./compiler/lua53.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 +if hasContinue then -- ./compiler/lua53.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 +end -- ./compiler/lua53.can:427 +return r .. unindent() .. "end" -- ./compiler/lua53.can:429 +else -- ./compiler/lua53.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 +if hasContinue then -- ./compiler/lua53.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 +end -- ./compiler/lua53.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 +if hasContinue then -- ./compiler/lua53.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 +end -- ./compiler/lua53.can:438 +return r .. unindent() .. "end" -- ./compiler/lua53.can:440 +end -- ./compiler/lua53.can:440 +end, -- ./compiler/lua53.can:440 +["Forin"] = function(t) -- ./compiler/lua53.can:444 +local destructured = {} -- ./compiler/lua53.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 +if hasContinue then -- ./compiler/lua53.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 +end -- ./compiler/lua53.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 +if hasContinue then -- ./compiler/lua53.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 +end -- ./compiler/lua53.can:453 +return r .. unindent() .. "end" -- ./compiler/lua53.can:455 +end, -- ./compiler/lua53.can:455 +["Local"] = function(t) -- ./compiler/lua53.can:458 +local destructured = {} -- ./compiler/lua53.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 +if t[2][1] then -- ./compiler/lua53.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 +end -- ./compiler/lua53.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 +end, -- ./compiler/lua53.can:464 +["Let"] = function(t) -- ./compiler/lua53.can:467 +local destructured = {} -- ./compiler/lua53.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 +local r = "local " .. nameList -- ./compiler/lua53.can:470 +if t[2][1] then -- ./compiler/lua53.can:471 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 +else -- ./compiler/lua53.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 +end, -- ./compiler/lua53.can:478 +["Localrec"] = function(t) -- ./compiler/lua53.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 +end, -- ./compiler/lua53.can:482 +["Goto"] = function(t) -- ./compiler/lua53.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 +end, -- ./compiler/lua53.can:486 +["Label"] = function(t) -- ./compiler/lua53.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 +end, -- ./compiler/lua53.can:490 +["Return"] = function(t) -- ./compiler/lua53.can:493 +local push = peek("push") -- ./compiler/lua53.can:494 +if push then -- ./compiler/lua53.can:495 +local r = "" -- ./compiler/lua53.can:496 +for _, val in ipairs(t) do -- ./compiler/lua53.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 +end -- ./compiler/lua53.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 +else -- ./compiler/lua53.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 +end -- ./compiler/lua53.can:502 +end, -- ./compiler/lua53.can:502 +["Push"] = function(t) -- ./compiler/lua53.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 +r = "" -- ./compiler/lua53.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 +end -- ./compiler/lua53.can:510 +if t[# t] then -- ./compiler/lua53.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 +else -- ./compiler/lua53.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +return r -- ./compiler/lua53.can:519 +end, -- ./compiler/lua53.can:519 +["Break"] = function() -- ./compiler/lua53.can:522 +return "break" -- ./compiler/lua53.can:523 +end, -- ./compiler/lua53.can:523 +["Continue"] = function() -- ./compiler/lua53.can:526 +return "goto " .. var("continue") -- ./compiler/lua53.can:527 +end, -- ./compiler/lua53.can:527 +["Nil"] = function() -- ./compiler/lua53.can:534 +return "nil" -- ./compiler/lua53.can:535 +end, -- ./compiler/lua53.can:535 +["Dots"] = function() -- ./compiler/lua53.can:538 +return "..." -- ./compiler/lua53.can:539 +end, -- ./compiler/lua53.can:539 +["Boolean"] = function(t) -- ./compiler/lua53.can:542 +return tostring(t[1]) -- ./compiler/lua53.can:543 +end, -- ./compiler/lua53.can:543 +["Number"] = function(t) -- ./compiler/lua53.can:546 +return tostring(t[1]) -- ./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 +["String"] = function(t) -- ./compiler/lua53.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 +end, -- ./compiler/lua53.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 +local r = "(" -- ./compiler/lua53.can:555 +local decl = {} -- ./compiler/lua53.can:556 +if t[1][1] then -- ./compiler/lua53.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 +r = r .. (id) -- ./compiler/lua53.can:563 +else -- ./compiler/lua53.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 +end -- ./compiler/lua53.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 +r = r .. (", " .. id) -- ./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 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 +r = r .. (d .. newline()) -- ./compiler/lua53.can:581 +end -- ./compiler/lua53.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 +end -- ./compiler/lua53.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 +if hasPush then -- ./compiler/lua53.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 +else -- ./compiler/lua53.can:588 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 +end -- ./compiler/lua53.can:594 +pop("push") -- ./compiler/lua53.can:596 +return r .. unindent() .. "end" -- ./compiler/lua53.can:597 +end, -- ./compiler/lua53.can:597 +["Function"] = function(t) -- ./compiler/lua53.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 +end, -- ./compiler/lua53.can:600 +["Pair"] = function(t) -- ./compiler/lua53.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 +end, -- ./compiler/lua53.can:604 +["Table"] = function(t) -- ./compiler/lua53.can:606 +if # t == 0 then -- ./compiler/lua53.can:607 +return "{}" -- ./compiler/lua53.can:608 +elseif # t == 1 then -- ./compiler/lua53.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 +else -- ./compiler/lua53.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 +end -- ./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 +["TableCompr"] = function(t) -- ./compiler/lua53.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 +end, -- ./compiler/lua53.can:617 +["Op"] = function(t) -- ./compiler/lua53.can:620 +local r -- ./compiler/lua53.can:621 +if # t == 2 then -- ./compiler/lua53.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 +else -- ./compiler/lua53.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 +end -- ./compiler/lua53.can:626 +else -- ./compiler/lua53.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 +else -- ./compiler/lua53.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./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:632 +return r -- ./compiler/lua53.can:635 +end, -- ./compiler/lua53.can:635 +["Paren"] = function(t) -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 +end, -- ./compiler/lua53.can:639 +["MethodStub"] = function(t) -- ./compiler/lua53.can:642 +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:648 +end, -- ./compiler/lua53.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 +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:658 +end, -- ./compiler/lua53.can:658 +["LetExpr"] = function(t) -- ./compiler/lua53.can:665 +return lua(t[1][1]) -- ./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 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 +local r = "(function()" .. indent() -- ./compiler/lua53.can:672 +if hasPush then -- ./compiler/lua53.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 +else -- ./compiler/lua53.can:674 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 +if hasPush then -- ./compiler/lua53.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 +end -- ./compiler/lua53.can:680 +pop("push") -- ./compiler/lua53.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 +return r -- ./compiler/lua53.can:684 +end, -- ./compiler/lua53.can:684 +["DoExpr"] = function(t) -- ./compiler/lua53.can:687 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +t[# t]["tag"] = "Return" -- ./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 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 +end, -- ./compiler/lua53.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 +end, -- ./compiler/lua53.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 +end, -- ./compiler/lua53.can:699 +["IfExpr"] = function(t) -- ./compiler/lua53.can:702 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +local block = t[i] -- ./compiler/lua53.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 +end, -- ./compiler/lua53.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 +end, -- ./compiler/lua53.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 +end, -- ./compiler/lua53.can:717 +["Call"] = function(t) -- ./compiler/lua53.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 +else -- ./compiler/lua53.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 +end -- ./compiler/lua53.can:730 +else -- ./compiler/lua53.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 +end -- ./compiler/lua53.can:733 +end, -- ./compiler/lua53.can:733 +["SafeCall"] = function(t) -- ./compiler/lua53.can:737 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 +else -- ./compiler/lua53.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 +end -- ./compiler/lua53.can:741 +end, -- ./compiler/lua53.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 +if start == nil then start = 1 end -- ./compiler/lua53.can:746 +local r -- ./compiler/lua53.can:747 +if t[start] then -- ./compiler/lua53.can:748 +r = lua(t[start]) -- ./compiler/lua53.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 +end -- ./compiler/lua53.can:751 +else -- ./compiler/lua53.can:751 +r = "" -- ./compiler/lua53.can:754 +end -- ./compiler/lua53.can:754 +return r -- ./compiler/lua53.can:756 +end, -- ./compiler/lua53.can:756 +["Id"] = function(t) -- ./compiler/lua53.can:759 +return t[1] -- ./compiler/lua53.can:760 +end, -- ./compiler/lua53.can:760 +["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 +if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +return t["id"] -- ./compiler/lua53.can:765 +else -- ./compiler/lua53.can:765 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 +local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 +for j = 1, # t, 1 do -- ./compiler/lua53.can:769 +table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 +end -- ./compiler/lua53.can:770 +table["insert"](d, vars) -- ./compiler/lua53.can:772 +t["id"] = vars["id"] -- ./compiler/lua53.can:773 +return vars["id"] -- ./compiler/lua53.can:774 +end -- ./compiler/lua53.can:774 +end, -- ./compiler/lua53.can:774 +["Index"] = function(t) -- ./compiler/lua53.can:778 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 +else -- ./compiler/lua53.can:780 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 +end -- ./compiler/lua53.can:782 +end, -- ./compiler/lua53.can:782 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 +table["insert"](l, 1, t) -- ./compiler/lua53.can:790 +t = t[1] -- ./compiler/lua53.can:791 +end -- ./compiler/lua53.can:791 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +for _, e in ipairs(l) do -- ./compiler/lua53.can:794 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 +else -- ./compiler/lua53.can:797 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 +return r -- ./compiler/lua53.can:803 +else -- ./compiler/lua53.can:803 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 +end -- ./compiler/lua53.can:805 +end, -- ./compiler/lua53.can:805 +["_opid"] = { -- ./compiler/lua53.can:810 +["add"] = "+", -- ./compiler/lua53.can:811 +["sub"] = "-", -- ./compiler/lua53.can:811 +["mul"] = "*", -- ./compiler/lua53.can:811 +["div"] = "/", -- ./compiler/lua53.can:811 +["idiv"] = "//", -- ./compiler/lua53.can:812 +["mod"] = "%", -- ./compiler/lua53.can:812 +["pow"] = "^", -- ./compiler/lua53.can:812 +["concat"] = "..", -- ./compiler/lua53.can:812 +["band"] = "&", -- ./compiler/lua53.can:813 +["bor"] = "|", -- ./compiler/lua53.can:813 +["bxor"] = "~", -- ./compiler/lua53.can:813 +["shl"] = "<<", -- ./compiler/lua53.can:813 +["shr"] = ">>", -- ./compiler/lua53.can:813 +["eq"] = "==", -- ./compiler/lua53.can:814 +["ne"] = "~=", -- ./compiler/lua53.can:814 +["lt"] = "<", -- ./compiler/lua53.can:814 +["gt"] = ">", -- ./compiler/lua53.can:814 +["le"] = "<=", -- ./compiler/lua53.can:814 +["ge"] = ">=", -- ./compiler/lua53.can:814 +["and"] = "and", -- ./compiler/lua53.can:815 +["or"] = "or", -- ./compiler/lua53.can:815 +["unm"] = "-", -- ./compiler/lua53.can:815 +["len"] = "#", -- ./compiler/lua53.can:815 +["bnot"] = "~", -- ./compiler/lua53.can:815 +["not"] = "not" -- ./compiler/lua53.can:815 +} -- ./compiler/lua53.can:815 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 +end }) -- ./compiler/lua53.can:819 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:825 +return requireStr .. code -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +local lua53 = _() or lua53 -- ./compiler/lua53.can:831 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:832 +local function _() -- ./compiler/lua53.can:835 +local function _() -- ./compiler/lua53.can:837 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 @@ -843,7 +997,7 @@ local r = options["newline"] .. string["rep"](options["indentation"], indentLeve 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+)\ +")):match(".*%-%- (.-)%:(%d+)\ ") -- ./compiler/lua53.can:17 if source and line then -- ./compiler/lua53.can:19 lastSource = source -- ./compiler/lua53.can:20 @@ -867,665 +1021,819 @@ 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 +local states = { -- ./compiler/lua53.can:47 +["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 +["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +local function push(name, state) -- ./compiler/lua53.can:53 +table["insert"](states[name], state) -- ./compiler/lua53.can:54 +return "" -- ./compiler/lua53.can:55 +end -- ./compiler/lua53.can:55 +local function pop(name) -- ./compiler/lua53.can:58 +table["remove"](states[name]) -- ./compiler/lua53.can:59 +return "" -- ./compiler/lua53.can:60 +end -- ./compiler/lua53.can:60 +local function set(name, state) -- ./compiler/lua53.can:63 +states[name][# states[name]] = state -- ./compiler/lua53.can:64 +return "" -- ./compiler/lua53.can:65 +end -- ./compiler/lua53.can:65 +local function peek(name) -- ./compiler/lua53.can:68 +return states[name][# states[name]] -- ./compiler/lua53.can:69 +end -- ./compiler/lua53.can:69 +local function var(name) -- ./compiler/lua53.can:74 +return options["variablePrefix"] .. name -- ./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 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 +local function tmp() -- ./compiler/lua53.can:79 +local scope = peek("scope") -- ./compiler/lua53.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 +table["insert"](scope, var) -- ./compiler/lua53.can:82 +return var -- ./compiler/lua53.can:83 +end -- ./compiler/lua53.can:83 +local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local requireStr = "" -- ./compiler/lua53.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 +if not required[req] then -- ./compiler/lua53.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 +required[req] = true -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 +local tagsCheck = {} -- ./compiler/lua53.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 +tagsCheck[tag] = true -- ./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 +local nofollowCheck = {} -- ./compiler/lua53.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 +nofollowCheck[tag] = true -- ./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 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 -end -- ./compiler/lua53.can:129 -return true -- ./compiler/lua53.can:132 +for _, node in ipairs(list) do -- ./compiler/lua53.can:113 +if type(node) == "table" then -- ./compiler/lua53.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 +return node -- ./compiler/lua53.can:116 +end -- ./compiler/lua53.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 +if r then -- ./compiler/lua53.can:120 +return r -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +return nil -- ./compiler/lua53.can:124 +end -- ./compiler/lua53.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 +local tagsCheck = {} -- ./compiler/lua53.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 +tagsCheck[tag] = 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 +local nofollowCheck = {} -- ./compiler/lua53.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 +nofollowCheck[tag] = true -- ./compiler/lua53.can:136 +end -- ./compiler/lua53.can:136 +local found = {} -- ./compiler/lua53.can:138 +for _, node in ipairs(list) do -- ./compiler/lua53.can:139 +if type(node) == "table" then -- ./compiler/lua53.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 +table["insert"](found, n) -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -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 -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 -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:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 +table["insert"](found, node) -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +return found -- ./compiler/lua53.can:151 +end -- ./compiler/lua53.can:151 +local function all(list, tags) -- ./compiler/lua53.can:155 +for _, node in ipairs(list) do -- ./compiler/lua53.can:156 +local ok = false -- ./compiler/lua53.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 +if node["tag"] == tag then -- ./compiler/lua53.can:159 +ok = true -- ./compiler/lua53.can:160 +break -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +if not ok then -- ./compiler/lua53.can:164 +return false -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +return true -- ./compiler/lua53.can:168 +end -- ./compiler/lua53.can:168 +local tags -- ./compiler/lua53.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 +lastInputPos = ast["pos"] -- ./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 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 +end -- ./compiler/lua53.can:178 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 +end -- ./compiler/lua53.can:183 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -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 -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 -- ./compiler/lua53.can:228 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +return "do" .. indent() -- ./compiler/lua53.can:189 +end -- ./compiler/lua53.can:189 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 +end -- ./compiler/lua53.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local vars = {} -- ./compiler/lua53.can:195 +local values = {} -- ./compiler/lua53.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 +for _, v in ipairs(list) do -- ./compiler/lua53.can:198 +local var, val -- ./compiler/lua53.can:199 +if v["tag"] == "Id" then -- ./compiler/lua53.can:200 +var = v -- ./compiler/lua53.can:201 +val = { -- ./compiler/lua53.can:202 +["tag"] = "Index", -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "Id", -- ./compiler/lua53.can:202 +list["id"] -- ./compiler/lua53.can:202 +}, -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "String", -- ./compiler/lua53.can:202 +v[1] -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 +var = v[2] -- ./compiler/lua53.can:204 +val = { -- ./compiler/lua53.can:205 +["tag"] = "Index", -- ./compiler/lua53.can:205 +{ -- ./compiler/lua53.can:205 +["tag"] = "Id", -- ./compiler/lua53.can:205 +list["id"] -- ./compiler/lua53.can:205 +}, -- ./compiler/lua53.can:205 +v[1] -- ./compiler/lua53.can:205 +} -- ./compiler/lua53.can:205 +else -- ./compiler/lua53.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 +end -- ./compiler/lua53.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 +val = { -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["rightOp"], -- ./compiler/lua53.can:210 +var, -- ./compiler/lua53.can:210 +{ -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["leftOp"], -- ./compiler/lua53.can:210 +val, -- ./compiler/lua53.can:210 +var -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 +val = { -- ./compiler/lua53.can:212 +["tag"] = "Op", -- ./compiler/lua53.can:212 +destructured["rightOp"], -- ./compiler/lua53.can:212 +var, -- ./compiler/lua53.can:212 +val -- ./compiler/lua53.can:212 +} -- ./compiler/lua53.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 +val = { -- ./compiler/lua53.can:214 +["tag"] = "Op", -- ./compiler/lua53.can:214 +destructured["leftOp"], -- ./compiler/lua53.can:214 +val, -- ./compiler/lua53.can:214 +var -- ./compiler/lua53.can:214 +} -- ./compiler/lua53.can:214 +end -- ./compiler/lua53.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +if # vars > 0 then -- ./compiler/lua53.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 +if newlineAfter then -- ./compiler/lua53.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 +else -- ./compiler/lua53.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 +end -- ./compiler/lua53.can:225 +else -- ./compiler/lua53.can:225 +return "" -- ./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:228 +tags = setmetatable({ -- ./compiler/lua53.can:233 +["Block"] = function(t) -- ./compiler/lua53.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 +hasPush = false -- ./compiler/lua53.can:239 +end -- ./compiler/lua53.can:239 +local r = push("scope", {}) -- ./compiler/lua53.can:241 +if hasPush then -- ./compiler/lua53.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 +end -- ./compiler/lua53.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 +r = r .. (lua(t[i]) .. 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 -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 -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 +if t[# t] then -- ./compiler/lua53.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 +end -- ./compiler/lua53.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 +end -- ./compiler/lua53.can:252 +return r .. pop("scope") -- ./compiler/lua53.can:254 +end, -- ./compiler/lua53.can:254 +["Do"] = function(t) -- ./compiler/lua53.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 +end, -- ./compiler/lua53.can:261 +["Set"] = function(t) -- ./compiler/lua53.can:264 +local expr = t[# t] -- ./compiler/lua53.can:266 +local vars, values = {}, {} -- ./compiler/lua53.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 +else -- ./compiler/lua53.can:272 +table["insert"](vars, n) -- ./compiler/lua53.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 +local r = "" -- ./compiler/lua53.can:280 +if # vars > 0 then -- ./compiler/lua53.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 +end -- ./compiler/lua53.can:282 +if # destructuringVars > 0 then -- ./compiler/lua53.can:284 +local destructured = {} -- ./compiler/lua53.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 +end -- ./compiler/lua53.can:287 +return r -- ./compiler/lua53.can:289 +elseif # t == 4 then -- ./compiler/lua53.can:290 +if t[3] == "=" then -- ./compiler/lua53.can:291 +local r = "" -- ./compiler/lua53.can:292 +if # vars > 0 then -- ./compiler/lua53.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 +t[2], -- ./compiler/lua53.can:294 +vars[1], -- ./compiler/lua53.can:294 +{ -- ./compiler/lua53.can:294 +["tag"] = "Paren", -- ./compiler/lua53.can:294 +values[1] -- ./compiler/lua53.can:294 +} -- ./compiler/lua53.can:294 +}, "Op")) -- ./compiler/lua53.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 +t[2], -- ./compiler/lua53.can:296 +vars[i], -- ./compiler/lua53.can:296 +{ -- ./compiler/lua53.can:296 +["tag"] = "Paren", -- ./compiler/lua53.can:296 +values[i] -- ./compiler/lua53.can:296 +} -- ./compiler/lua53.can:296 +}, "Op")) -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +if # destructuringVars > 0 then -- ./compiler/lua53.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./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 +return r -- ./compiler/lua53.can:304 +else -- ./compiler/lua53.can:304 +local r = "" -- ./compiler/lua53.can:306 +if # vars > 0 then -- ./compiler/lua53.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 +t[3], -- ./compiler/lua53.can:308 +{ -- ./compiler/lua53.can:308 +["tag"] = "Paren", -- ./compiler/lua53.can:308 +values[1] -- ./compiler/lua53.can:308 +}, -- ./compiler/lua53.can:308 +vars[1] -- ./compiler/lua53.can:308 +}, "Op")) -- ./compiler/lua53.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 +t[3], -- ./compiler/lua53.can:310 +{ -- ./compiler/lua53.can:310 +["tag"] = "Paren", -- ./compiler/lua53.can:310 +values[i] -- ./compiler/lua53.can:310 +}, -- ./compiler/lua53.can:310 +vars[i] -- ./compiler/lua53.can:310 +}, "Op")) -- ./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:310 +if # destructuringVars > 0 then -- ./compiler/lua53.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 +end -- ./compiler/lua53.can:316 +return r -- ./compiler/lua53.can:318 +end -- ./compiler/lua53.can:318 +else -- ./compiler/lua53.can:318 +local r = "" -- ./compiler/lua53.can:321 +if # vars > 0 then -- ./compiler/lua53.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 +t[2], -- ./compiler/lua53.can:323 +vars[1], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Op", -- ./compiler/lua53.can:323 +t[4], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Paren", -- ./compiler/lua53.can:323 +values[1] -- ./compiler/lua53.can:323 +}, -- ./compiler/lua53.can:323 +vars[1] -- ./compiler/lua53.can:323 +} -- ./compiler/lua53.can:323 +}, "Op")) -- ./compiler/lua53.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 +t[2], -- ./compiler/lua53.can:325 +vars[i], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Op", -- ./compiler/lua53.can:325 +t[4], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Paren", -- ./compiler/lua53.can:325 +values[i] -- ./compiler/lua53.can:325 +}, -- ./compiler/lua53.can:325 +vars[i] -- ./compiler/lua53.can:325 +} -- ./compiler/lua53.can:325 +}, "Op")) -- ./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 -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 -["String"] = function(t) -- ./compiler/lua53.can:449 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 -end, -- ./compiler/lua53.can:450 -["_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 -pop("push") -- ./compiler/lua53.can:495 -return r .. unindent() .. "end" -- ./compiler/lua53.can:496 -end, -- ./compiler/lua53.can:496 -["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 -["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:325 +if # destructuringVars > 0 then -- ./compiler/lua53.can:328 +local destructured = { -- ./compiler/lua53.can:329 +["rightOp"] = t[2], -- ./compiler/lua53.can:329 +["leftOp"] = t[4] -- ./compiler/lua53.can:329 +} -- ./compiler/lua53.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 +end -- ./compiler/lua53.can:331 +return r -- ./compiler/lua53.can:333 +end -- ./compiler/lua53.can:333 +end, -- ./compiler/lua53.can:333 +["While"] = function(t) -- ./compiler/lua53.can:337 +local r = "" -- ./compiler/lua53.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 +if # lets > 0 then -- ./compiler/lua53.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 +if # lets > 0 then -- ./compiler/lua53.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 +end -- ./compiler/lua53.can:349 +if hasContinue then -- ./compiler/lua53.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 +end -- ./compiler/lua53.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 +if hasContinue then -- ./compiler/lua53.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 +end -- ./compiler/lua53.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 +if # lets > 0 then -- ./compiler/lua53.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 +end -- ./compiler/lua53.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 +end -- ./compiler/lua53.can:363 +return r -- ./compiler/lua53.can:365 +end, -- ./compiler/lua53.can:365 +["Repeat"] = function(t) -- ./compiler/lua53.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 +local r = "repeat" .. indent() -- ./compiler/lua53.can:370 +if hasContinue then -- ./compiler/lua53.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 +end -- ./compiler/lua53.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 +if hasContinue then -- ./compiler/lua53.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 +end -- ./compiler/lua53.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 +return r -- ./compiler/lua53.can:379 +end, -- ./compiler/lua53.can:379 +["If"] = function(t) -- ./compiler/lua53.can:382 +local r = "" -- ./compiler/lua53.can:383 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 +if # lets > 0 then -- ./compiler/lua53.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 +toClose = toClose + (1) -- ./compiler/lua53.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 +if # lets > 0 then -- ./compiler/lua53.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 +toClose = toClose + (1) -- ./compiler/lua53.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 +end -- ./compiler/lua53.can:400 +else -- ./compiler/lua53.can:400 +r = r .. ("else") -- ./compiler/lua53.can:403 +end -- ./compiler/lua53.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 +end -- ./compiler/lua53.can:405 +if # t % 2 == 1 then -- ./compiler/lua53.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 +end -- ./compiler/lua53.can:408 +r = r .. ("end") -- ./compiler/lua53.can:410 +for i = 1, toClose do -- ./compiler/lua53.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 +end -- ./compiler/lua53.can:412 +return r -- ./compiler/lua53.can:414 +end, -- ./compiler/lua53.can:414 +["Fornum"] = function(t) -- ./compiler/lua53.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 +if # t == 5 then -- ./compiler/lua53.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 +if hasContinue then -- ./compiler/lua53.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 +end -- ./compiler/lua53.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 +if hasContinue then -- ./compiler/lua53.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 +end -- ./compiler/lua53.can:427 +return r .. unindent() .. "end" -- ./compiler/lua53.can:429 +else -- ./compiler/lua53.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 +if hasContinue then -- ./compiler/lua53.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 +end -- ./compiler/lua53.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 +if hasContinue then -- ./compiler/lua53.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 +end -- ./compiler/lua53.can:438 +return r .. unindent() .. "end" -- ./compiler/lua53.can:440 +end -- ./compiler/lua53.can:440 +end, -- ./compiler/lua53.can:440 +["Forin"] = function(t) -- ./compiler/lua53.can:444 +local destructured = {} -- ./compiler/lua53.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 +if hasContinue then -- ./compiler/lua53.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 +end -- ./compiler/lua53.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 +if hasContinue then -- ./compiler/lua53.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 +end -- ./compiler/lua53.can:453 +return r .. unindent() .. "end" -- ./compiler/lua53.can:455 +end, -- ./compiler/lua53.can:455 +["Local"] = function(t) -- ./compiler/lua53.can:458 +local destructured = {} -- ./compiler/lua53.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 +if t[2][1] then -- ./compiler/lua53.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 +end -- ./compiler/lua53.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 +end, -- ./compiler/lua53.can:464 +["Let"] = function(t) -- ./compiler/lua53.can:467 +local destructured = {} -- ./compiler/lua53.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 +local r = "local " .. nameList -- ./compiler/lua53.can:470 +if t[2][1] then -- ./compiler/lua53.can:471 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 +else -- ./compiler/lua53.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 +end, -- ./compiler/lua53.can:478 +["Localrec"] = function(t) -- ./compiler/lua53.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 +end, -- ./compiler/lua53.can:482 +["Goto"] = function(t) -- ./compiler/lua53.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 +end, -- ./compiler/lua53.can:486 +["Label"] = function(t) -- ./compiler/lua53.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 +end, -- ./compiler/lua53.can:490 +["Return"] = function(t) -- ./compiler/lua53.can:493 +local push = peek("push") -- ./compiler/lua53.can:494 +if push then -- ./compiler/lua53.can:495 +local r = "" -- ./compiler/lua53.can:496 +for _, val in ipairs(t) do -- ./compiler/lua53.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 +end -- ./compiler/lua53.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 +else -- ./compiler/lua53.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 +end -- ./compiler/lua53.can:502 +end, -- ./compiler/lua53.can:502 +["Push"] = function(t) -- ./compiler/lua53.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 +r = "" -- ./compiler/lua53.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 +end -- ./compiler/lua53.can:510 +if t[# t] then -- ./compiler/lua53.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 +else -- ./compiler/lua53.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +return r -- ./compiler/lua53.can:519 +end, -- ./compiler/lua53.can:519 +["Break"] = function() -- ./compiler/lua53.can:522 +return "break" -- ./compiler/lua53.can:523 +end, -- ./compiler/lua53.can:523 +["Continue"] = function() -- ./compiler/lua53.can:526 +return "goto " .. var("continue") -- ./compiler/lua53.can:527 +end, -- ./compiler/lua53.can:527 +["Nil"] = function() -- ./compiler/lua53.can:534 +return "nil" -- ./compiler/lua53.can:535 +end, -- ./compiler/lua53.can:535 +["Dots"] = function() -- ./compiler/lua53.can:538 +return "..." -- ./compiler/lua53.can:539 +end, -- ./compiler/lua53.can:539 +["Boolean"] = function(t) -- ./compiler/lua53.can:542 +return tostring(t[1]) -- ./compiler/lua53.can:543 +end, -- ./compiler/lua53.can:543 +["Number"] = function(t) -- ./compiler/lua53.can:546 +return tostring(t[1]) -- ./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 +["String"] = function(t) -- ./compiler/lua53.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 +end, -- ./compiler/lua53.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 +local r = "(" -- ./compiler/lua53.can:555 +local decl = {} -- ./compiler/lua53.can:556 +if t[1][1] then -- ./compiler/lua53.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 +r = r .. (id) -- ./compiler/lua53.can:563 +else -- ./compiler/lua53.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 +end -- ./compiler/lua53.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 +r = r .. (", " .. id) -- ./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 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 +r = r .. (d .. newline()) -- ./compiler/lua53.can:581 +end -- ./compiler/lua53.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 +end -- ./compiler/lua53.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 +if hasPush then -- ./compiler/lua53.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 +else -- ./compiler/lua53.can:588 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 +end -- ./compiler/lua53.can:594 +pop("push") -- ./compiler/lua53.can:596 +return r .. unindent() .. "end" -- ./compiler/lua53.can:597 +end, -- ./compiler/lua53.can:597 +["Function"] = function(t) -- ./compiler/lua53.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 +end, -- ./compiler/lua53.can:600 +["Pair"] = function(t) -- ./compiler/lua53.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 +end, -- ./compiler/lua53.can:604 +["Table"] = function(t) -- ./compiler/lua53.can:606 +if # t == 0 then -- ./compiler/lua53.can:607 +return "{}" -- ./compiler/lua53.can:608 +elseif # t == 1 then -- ./compiler/lua53.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 +else -- ./compiler/lua53.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 +end -- ./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 +["TableCompr"] = function(t) -- ./compiler/lua53.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 +end, -- ./compiler/lua53.can:617 +["Op"] = function(t) -- ./compiler/lua53.can:620 +local r -- ./compiler/lua53.can:621 +if # t == 2 then -- ./compiler/lua53.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 +else -- ./compiler/lua53.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 +end -- ./compiler/lua53.can:626 +else -- ./compiler/lua53.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 +else -- ./compiler/lua53.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./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:632 +return r -- ./compiler/lua53.can:635 +end, -- ./compiler/lua53.can:635 +["Paren"] = function(t) -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 +end, -- ./compiler/lua53.can:639 +["MethodStub"] = function(t) -- ./compiler/lua53.can:642 +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:648 +end, -- ./compiler/lua53.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 +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:658 +end, -- ./compiler/lua53.can:658 +["LetExpr"] = function(t) -- ./compiler/lua53.can:665 +return lua(t[1][1]) -- ./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 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 +local r = "(function()" .. indent() -- ./compiler/lua53.can:672 +if hasPush then -- ./compiler/lua53.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 +else -- ./compiler/lua53.can:674 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 +if hasPush then -- ./compiler/lua53.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 +end -- ./compiler/lua53.can:680 +pop("push") -- ./compiler/lua53.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 +return r -- ./compiler/lua53.can:684 +end, -- ./compiler/lua53.can:684 +["DoExpr"] = function(t) -- ./compiler/lua53.can:687 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +t[# t]["tag"] = "Return" -- ./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 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 +end, -- ./compiler/lua53.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 +end, -- ./compiler/lua53.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 +end, -- ./compiler/lua53.can:699 +["IfExpr"] = function(t) -- ./compiler/lua53.can:702 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +local block = t[i] -- ./compiler/lua53.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 +end, -- ./compiler/lua53.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 +end, -- ./compiler/lua53.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 +end, -- ./compiler/lua53.can:717 +["Call"] = function(t) -- ./compiler/lua53.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 +else -- ./compiler/lua53.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 +end -- ./compiler/lua53.can:730 +else -- ./compiler/lua53.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 +end -- ./compiler/lua53.can:733 +end, -- ./compiler/lua53.can:733 +["SafeCall"] = function(t) -- ./compiler/lua53.can:737 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 +else -- ./compiler/lua53.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 +end -- ./compiler/lua53.can:741 +end, -- ./compiler/lua53.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 +if start == nil then start = 1 end -- ./compiler/lua53.can:746 +local r -- ./compiler/lua53.can:747 +if t[start] then -- ./compiler/lua53.can:748 +r = lua(t[start]) -- ./compiler/lua53.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 +end -- ./compiler/lua53.can:751 +else -- ./compiler/lua53.can:751 +r = "" -- ./compiler/lua53.can:754 +end -- ./compiler/lua53.can:754 +return r -- ./compiler/lua53.can:756 +end, -- ./compiler/lua53.can:756 +["Id"] = function(t) -- ./compiler/lua53.can:759 +return t[1] -- ./compiler/lua53.can:760 +end, -- ./compiler/lua53.can:760 +["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 +if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +return t["id"] -- ./compiler/lua53.can:765 +else -- ./compiler/lua53.can:765 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 +local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 +for j = 1, # t, 1 do -- ./compiler/lua53.can:769 +table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 +end -- ./compiler/lua53.can:770 +table["insert"](d, vars) -- ./compiler/lua53.can:772 +t["id"] = vars["id"] -- ./compiler/lua53.can:773 +return vars["id"] -- ./compiler/lua53.can:774 +end -- ./compiler/lua53.can:774 +end, -- ./compiler/lua53.can:774 +["Index"] = function(t) -- ./compiler/lua53.can:778 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 +else -- ./compiler/lua53.can:780 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 +end -- ./compiler/lua53.can:782 +end, -- ./compiler/lua53.can:782 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 +table["insert"](l, 1, t) -- ./compiler/lua53.can:790 +t = t[1] -- ./compiler/lua53.can:791 +end -- ./compiler/lua53.can:791 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +for _, e in ipairs(l) do -- ./compiler/lua53.can:794 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 +else -- ./compiler/lua53.can:797 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 +return r -- ./compiler/lua53.can:803 +else -- ./compiler/lua53.can:803 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 +end -- ./compiler/lua53.can:805 +end, -- ./compiler/lua53.can:805 +["_opid"] = { -- ./compiler/lua53.can:810 +["add"] = "+", -- ./compiler/lua53.can:811 +["sub"] = "-", -- ./compiler/lua53.can:811 +["mul"] = "*", -- ./compiler/lua53.can:811 +["div"] = "/", -- ./compiler/lua53.can:811 +["idiv"] = "//", -- ./compiler/lua53.can:812 +["mod"] = "%", -- ./compiler/lua53.can:812 +["pow"] = "^", -- ./compiler/lua53.can:812 +["concat"] = "..", -- ./compiler/lua53.can:812 +["band"] = "&", -- ./compiler/lua53.can:813 +["bor"] = "|", -- ./compiler/lua53.can:813 +["bxor"] = "~", -- ./compiler/lua53.can:813 +["shl"] = "<<", -- ./compiler/lua53.can:813 +["shr"] = ">>", -- ./compiler/lua53.can:813 +["eq"] = "==", -- ./compiler/lua53.can:814 +["ne"] = "~=", -- ./compiler/lua53.can:814 +["lt"] = "<", -- ./compiler/lua53.can:814 +["gt"] = ">", -- ./compiler/lua53.can:814 +["le"] = "<=", -- ./compiler/lua53.can:814 +["ge"] = ">=", -- ./compiler/lua53.can:814 +["and"] = "and", -- ./compiler/lua53.can:815 +["or"] = "or", -- ./compiler/lua53.can:815 +["unm"] = "-", -- ./compiler/lua53.can:815 +["len"] = "#", -- ./compiler/lua53.can:815 +["bnot"] = "~", -- ./compiler/lua53.can:815 +["not"] = "not" -- ./compiler/lua53.can:815 +} -- ./compiler/lua53.can:815 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 +end }) -- ./compiler/lua53.can:819 +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 @@ -1559,11 +1867,11 @@ 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 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:825 +return requireStr .. code -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +local lua53 = _() or lua53 -- ./compiler/lua53.can:831 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 @@ -1583,7 +1891,7 @@ local r = options["newline"] .. string["rep"](options["indentation"], indentLeve 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+)\ +")):match(".*%-%- (.-)%:(%d+)\ ") -- ./compiler/lua53.can:17 if source and line then -- ./compiler/lua53.can:19 lastSource = source -- ./compiler/lua53.can:20 @@ -1607,665 +1915,819 @@ 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 +local states = { -- ./compiler/lua53.can:47 +["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 +["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +local function push(name, state) -- ./compiler/lua53.can:53 +table["insert"](states[name], state) -- ./compiler/lua53.can:54 +return "" -- ./compiler/lua53.can:55 +end -- ./compiler/lua53.can:55 +local function pop(name) -- ./compiler/lua53.can:58 +table["remove"](states[name]) -- ./compiler/lua53.can:59 +return "" -- ./compiler/lua53.can:60 +end -- ./compiler/lua53.can:60 +local function set(name, state) -- ./compiler/lua53.can:63 +states[name][# states[name]] = state -- ./compiler/lua53.can:64 +return "" -- ./compiler/lua53.can:65 +end -- ./compiler/lua53.can:65 +local function peek(name) -- ./compiler/lua53.can:68 +return states[name][# states[name]] -- ./compiler/lua53.can:69 +end -- ./compiler/lua53.can:69 +local function var(name) -- ./compiler/lua53.can:74 +return options["variablePrefix"] .. name -- ./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 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 +local function tmp() -- ./compiler/lua53.can:79 +local scope = peek("scope") -- ./compiler/lua53.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 +table["insert"](scope, var) -- ./compiler/lua53.can:82 +return var -- ./compiler/lua53.can:83 +end -- ./compiler/lua53.can:83 +local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local requireStr = "" -- ./compiler/lua53.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 +if not required[req] then -- ./compiler/lua53.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 +required[req] = true -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +end -- ./compiler/lua53.can:94 +local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 +local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 +local tagsCheck = {} -- ./compiler/lua53.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 +tagsCheck[tag] = true -- ./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 +local nofollowCheck = {} -- ./compiler/lua53.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 +nofollowCheck[tag] = true -- ./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 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 -end -- ./compiler/lua53.can:129 -return true -- ./compiler/lua53.can:132 +for _, node in ipairs(list) do -- ./compiler/lua53.can:113 +if type(node) == "table" then -- ./compiler/lua53.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 +return node -- ./compiler/lua53.can:116 +end -- ./compiler/lua53.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 +if r then -- ./compiler/lua53.can:120 +return r -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +end -- ./compiler/lua53.can:120 +return nil -- ./compiler/lua53.can:124 +end -- ./compiler/lua53.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 +local tagsCheck = {} -- ./compiler/lua53.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 +tagsCheck[tag] = 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 +local nofollowCheck = {} -- ./compiler/lua53.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 +nofollowCheck[tag] = true -- ./compiler/lua53.can:136 +end -- ./compiler/lua53.can:136 +local found = {} -- ./compiler/lua53.can:138 +for _, node in ipairs(list) do -- ./compiler/lua53.can:139 +if type(node) == "table" then -- ./compiler/lua53.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 +table["insert"](found, n) -- ./compiler/lua53.can:143 end -- ./compiler/lua53.can:143 -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 -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 -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:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 +table["insert"](found, node) -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +end -- ./compiler/lua53.can:147 +return found -- ./compiler/lua53.can:151 +end -- ./compiler/lua53.can:151 +local function all(list, tags) -- ./compiler/lua53.can:155 +for _, node in ipairs(list) do -- ./compiler/lua53.can:156 +local ok = false -- ./compiler/lua53.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 +if node["tag"] == tag then -- ./compiler/lua53.can:159 +ok = true -- ./compiler/lua53.can:160 +break -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +end -- ./compiler/lua53.can:161 +if not ok then -- ./compiler/lua53.can:164 +return false -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +end -- ./compiler/lua53.can:165 +return true -- ./compiler/lua53.can:168 +end -- ./compiler/lua53.can:168 +local tags -- ./compiler/lua53.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 +lastInputPos = ast["pos"] -- ./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 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 +end -- ./compiler/lua53.can:178 +local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 +end -- ./compiler/lua53.can:183 +local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -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 -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 -- ./compiler/lua53.can:228 +local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +return "do" .. indent() -- ./compiler/lua53.can:189 +end -- ./compiler/lua53.can:189 +local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 +end -- ./compiler/lua53.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local vars = {} -- ./compiler/lua53.can:195 +local values = {} -- ./compiler/lua53.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 +for _, v in ipairs(list) do -- ./compiler/lua53.can:198 +local var, val -- ./compiler/lua53.can:199 +if v["tag"] == "Id" then -- ./compiler/lua53.can:200 +var = v -- ./compiler/lua53.can:201 +val = { -- ./compiler/lua53.can:202 +["tag"] = "Index", -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "Id", -- ./compiler/lua53.can:202 +list["id"] -- ./compiler/lua53.can:202 +}, -- ./compiler/lua53.can:202 +{ -- ./compiler/lua53.can:202 +["tag"] = "String", -- ./compiler/lua53.can:202 +v[1] -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +} -- ./compiler/lua53.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 +var = v[2] -- ./compiler/lua53.can:204 +val = { -- ./compiler/lua53.can:205 +["tag"] = "Index", -- ./compiler/lua53.can:205 +{ -- ./compiler/lua53.can:205 +["tag"] = "Id", -- ./compiler/lua53.can:205 +list["id"] -- ./compiler/lua53.can:205 +}, -- ./compiler/lua53.can:205 +v[1] -- ./compiler/lua53.can:205 +} -- ./compiler/lua53.can:205 +else -- ./compiler/lua53.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 +end -- ./compiler/lua53.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 +val = { -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["rightOp"], -- ./compiler/lua53.can:210 +var, -- ./compiler/lua53.can:210 +{ -- ./compiler/lua53.can:210 +["tag"] = "Op", -- ./compiler/lua53.can:210 +destructured["leftOp"], -- ./compiler/lua53.can:210 +val, -- ./compiler/lua53.can:210 +var -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +} -- ./compiler/lua53.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 +val = { -- ./compiler/lua53.can:212 +["tag"] = "Op", -- ./compiler/lua53.can:212 +destructured["rightOp"], -- ./compiler/lua53.can:212 +var, -- ./compiler/lua53.can:212 +val -- ./compiler/lua53.can:212 +} -- ./compiler/lua53.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 +val = { -- ./compiler/lua53.can:214 +["tag"] = "Op", -- ./compiler/lua53.can:214 +destructured["leftOp"], -- ./compiler/lua53.can:214 +val, -- ./compiler/lua53.can:214 +var -- ./compiler/lua53.can:214 +} -- ./compiler/lua53.can:214 +end -- ./compiler/lua53.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +end -- ./compiler/lua53.can:217 +if # vars > 0 then -- ./compiler/lua53.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 +if newlineAfter then -- ./compiler/lua53.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 +else -- ./compiler/lua53.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 +end -- ./compiler/lua53.can:225 +else -- ./compiler/lua53.can:225 +return "" -- ./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:228 +tags = setmetatable({ -- ./compiler/lua53.can:233 +["Block"] = function(t) -- ./compiler/lua53.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 +hasPush = false -- ./compiler/lua53.can:239 +end -- ./compiler/lua53.can:239 +local r = push("scope", {}) -- ./compiler/lua53.can:241 +if hasPush then -- ./compiler/lua53.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 +end -- ./compiler/lua53.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 +r = r .. (lua(t[i]) .. 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 -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 -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 +if t[# t] then -- ./compiler/lua53.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 +end -- ./compiler/lua53.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 +end -- ./compiler/lua53.can:252 +return r .. pop("scope") -- ./compiler/lua53.can:254 +end, -- ./compiler/lua53.can:254 +["Do"] = function(t) -- ./compiler/lua53.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 +end, -- ./compiler/lua53.can:261 +["Set"] = function(t) -- ./compiler/lua53.can:264 +local expr = t[# t] -- ./compiler/lua53.can:266 +local vars, values = {}, {} -- ./compiler/lua53.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 +else -- ./compiler/lua53.can:272 +table["insert"](vars, n) -- ./compiler/lua53.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +end -- ./compiler/lua53.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 +local r = "" -- ./compiler/lua53.can:280 +if # vars > 0 then -- ./compiler/lua53.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 +end -- ./compiler/lua53.can:282 +if # destructuringVars > 0 then -- ./compiler/lua53.can:284 +local destructured = {} -- ./compiler/lua53.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 +end -- ./compiler/lua53.can:287 +return r -- ./compiler/lua53.can:289 +elseif # t == 4 then -- ./compiler/lua53.can:290 +if t[3] == "=" then -- ./compiler/lua53.can:291 +local r = "" -- ./compiler/lua53.can:292 +if # vars > 0 then -- ./compiler/lua53.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 +t[2], -- ./compiler/lua53.can:294 +vars[1], -- ./compiler/lua53.can:294 +{ -- ./compiler/lua53.can:294 +["tag"] = "Paren", -- ./compiler/lua53.can:294 +values[1] -- ./compiler/lua53.can:294 +} -- ./compiler/lua53.can:294 +}, "Op")) -- ./compiler/lua53.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 +t[2], -- ./compiler/lua53.can:296 +vars[i], -- ./compiler/lua53.can:296 +{ -- ./compiler/lua53.can:296 +["tag"] = "Paren", -- ./compiler/lua53.can:296 +values[i] -- ./compiler/lua53.can:296 +} -- ./compiler/lua53.can:296 +}, "Op")) -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +end -- ./compiler/lua53.can:296 +if # destructuringVars > 0 then -- ./compiler/lua53.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./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 +return r -- ./compiler/lua53.can:304 +else -- ./compiler/lua53.can:304 +local r = "" -- ./compiler/lua53.can:306 +if # vars > 0 then -- ./compiler/lua53.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 +t[3], -- ./compiler/lua53.can:308 +{ -- ./compiler/lua53.can:308 +["tag"] = "Paren", -- ./compiler/lua53.can:308 +values[1] -- ./compiler/lua53.can:308 +}, -- ./compiler/lua53.can:308 +vars[1] -- ./compiler/lua53.can:308 +}, "Op")) -- ./compiler/lua53.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 +t[3], -- ./compiler/lua53.can:310 +{ -- ./compiler/lua53.can:310 +["tag"] = "Paren", -- ./compiler/lua53.can:310 +values[i] -- ./compiler/lua53.can:310 +}, -- ./compiler/lua53.can:310 +vars[i] -- ./compiler/lua53.can:310 +}, "Op")) -- ./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:310 +if # destructuringVars > 0 then -- ./compiler/lua53.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 +end -- ./compiler/lua53.can:316 +return r -- ./compiler/lua53.can:318 +end -- ./compiler/lua53.can:318 +else -- ./compiler/lua53.can:318 +local r = "" -- ./compiler/lua53.can:321 +if # vars > 0 then -- ./compiler/lua53.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 +t[2], -- ./compiler/lua53.can:323 +vars[1], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Op", -- ./compiler/lua53.can:323 +t[4], -- ./compiler/lua53.can:323 +{ -- ./compiler/lua53.can:323 +["tag"] = "Paren", -- ./compiler/lua53.can:323 +values[1] -- ./compiler/lua53.can:323 +}, -- ./compiler/lua53.can:323 +vars[1] -- ./compiler/lua53.can:323 +} -- ./compiler/lua53.can:323 +}, "Op")) -- ./compiler/lua53.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 +t[2], -- ./compiler/lua53.can:325 +vars[i], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Op", -- ./compiler/lua53.can:325 +t[4], -- ./compiler/lua53.can:325 +{ -- ./compiler/lua53.can:325 +["tag"] = "Paren", -- ./compiler/lua53.can:325 +values[i] -- ./compiler/lua53.can:325 +}, -- ./compiler/lua53.can:325 +vars[i] -- ./compiler/lua53.can:325 +} -- ./compiler/lua53.can:325 +}, "Op")) -- ./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 -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 -["String"] = function(t) -- ./compiler/lua53.can:449 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:450 -end, -- ./compiler/lua53.can:450 -["_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 -pop("push") -- ./compiler/lua53.can:495 -return r .. unindent() .. "end" -- ./compiler/lua53.can:496 -end, -- ./compiler/lua53.can:496 -["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 -["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:325 +if # destructuringVars > 0 then -- ./compiler/lua53.can:328 +local destructured = { -- ./compiler/lua53.can:329 +["rightOp"] = t[2], -- ./compiler/lua53.can:329 +["leftOp"] = t[4] -- ./compiler/lua53.can:329 +} -- ./compiler/lua53.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 +end -- ./compiler/lua53.can:331 +return r -- ./compiler/lua53.can:333 +end -- ./compiler/lua53.can:333 +end, -- ./compiler/lua53.can:333 +["While"] = function(t) -- ./compiler/lua53.can:337 +local r = "" -- ./compiler/lua53.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 +if # lets > 0 then -- ./compiler/lua53.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +end -- ./compiler/lua53.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 +if # lets > 0 then -- ./compiler/lua53.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 +end -- ./compiler/lua53.can:349 +if hasContinue then -- ./compiler/lua53.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 +end -- ./compiler/lua53.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 +if hasContinue then -- ./compiler/lua53.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 +end -- ./compiler/lua53.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 +if # lets > 0 then -- ./compiler/lua53.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 +end -- ./compiler/lua53.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 +end -- ./compiler/lua53.can:363 +return r -- ./compiler/lua53.can:365 +end, -- ./compiler/lua53.can:365 +["Repeat"] = function(t) -- ./compiler/lua53.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 +local r = "repeat" .. indent() -- ./compiler/lua53.can:370 +if hasContinue then -- ./compiler/lua53.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 +end -- ./compiler/lua53.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 +if hasContinue then -- ./compiler/lua53.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 +end -- ./compiler/lua53.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 +return r -- ./compiler/lua53.can:379 +end, -- ./compiler/lua53.can:379 +["If"] = function(t) -- ./compiler/lua53.can:382 +local r = "" -- ./compiler/lua53.can:383 +local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 +if # lets > 0 then -- ./compiler/lua53.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 +toClose = toClose + (1) -- ./compiler/lua53.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +end -- ./compiler/lua53.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 +if # lets > 0 then -- ./compiler/lua53.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 +toClose = toClose + (1) -- ./compiler/lua53.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 +end -- ./compiler/lua53.can:400 +else -- ./compiler/lua53.can:400 +r = r .. ("else") -- ./compiler/lua53.can:403 +end -- ./compiler/lua53.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 +end -- ./compiler/lua53.can:405 +if # t % 2 == 1 then -- ./compiler/lua53.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 +end -- ./compiler/lua53.can:408 +r = r .. ("end") -- ./compiler/lua53.can:410 +for i = 1, toClose do -- ./compiler/lua53.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 +end -- ./compiler/lua53.can:412 +return r -- ./compiler/lua53.can:414 +end, -- ./compiler/lua53.can:414 +["Fornum"] = function(t) -- ./compiler/lua53.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 +if # t == 5 then -- ./compiler/lua53.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 +if hasContinue then -- ./compiler/lua53.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 +end -- ./compiler/lua53.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 +if hasContinue then -- ./compiler/lua53.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 +end -- ./compiler/lua53.can:427 +return r .. unindent() .. "end" -- ./compiler/lua53.can:429 +else -- ./compiler/lua53.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 +if hasContinue then -- ./compiler/lua53.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 +end -- ./compiler/lua53.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 +if hasContinue then -- ./compiler/lua53.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 +end -- ./compiler/lua53.can:438 +return r .. unindent() .. "end" -- ./compiler/lua53.can:440 +end -- ./compiler/lua53.can:440 +end, -- ./compiler/lua53.can:440 +["Forin"] = function(t) -- ./compiler/lua53.can:444 +local destructured = {} -- ./compiler/lua53.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 +if hasContinue then -- ./compiler/lua53.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 +end -- ./compiler/lua53.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 +if hasContinue then -- ./compiler/lua53.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 +end -- ./compiler/lua53.can:453 +return r .. unindent() .. "end" -- ./compiler/lua53.can:455 +end, -- ./compiler/lua53.can:455 +["Local"] = function(t) -- ./compiler/lua53.can:458 +local destructured = {} -- ./compiler/lua53.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 +if t[2][1] then -- ./compiler/lua53.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 +end -- ./compiler/lua53.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 +end, -- ./compiler/lua53.can:464 +["Let"] = function(t) -- ./compiler/lua53.can:467 +local destructured = {} -- ./compiler/lua53.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 +local r = "local " .. nameList -- ./compiler/lua53.can:470 +if t[2][1] then -- ./compiler/lua53.can:471 +if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 +else -- ./compiler/lua53.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +end -- ./compiler/lua53.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 +end, -- ./compiler/lua53.can:478 +["Localrec"] = function(t) -- ./compiler/lua53.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 +end, -- ./compiler/lua53.can:482 +["Goto"] = function(t) -- ./compiler/lua53.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 +end, -- ./compiler/lua53.can:486 +["Label"] = function(t) -- ./compiler/lua53.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 +end, -- ./compiler/lua53.can:490 +["Return"] = function(t) -- ./compiler/lua53.can:493 +local push = peek("push") -- ./compiler/lua53.can:494 +if push then -- ./compiler/lua53.can:495 +local r = "" -- ./compiler/lua53.can:496 +for _, val in ipairs(t) do -- ./compiler/lua53.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 +end -- ./compiler/lua53.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 +else -- ./compiler/lua53.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 +end -- ./compiler/lua53.can:502 +end, -- ./compiler/lua53.can:502 +["Push"] = function(t) -- ./compiler/lua53.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 +r = "" -- ./compiler/lua53.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 +end -- ./compiler/lua53.can:510 +if t[# t] then -- ./compiler/lua53.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 +else -- ./compiler/lua53.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +end -- ./compiler/lua53.can:516 +return r -- ./compiler/lua53.can:519 +end, -- ./compiler/lua53.can:519 +["Break"] = function() -- ./compiler/lua53.can:522 +return "break" -- ./compiler/lua53.can:523 +end, -- ./compiler/lua53.can:523 +["Continue"] = function() -- ./compiler/lua53.can:526 +return "goto " .. var("continue") -- ./compiler/lua53.can:527 +end, -- ./compiler/lua53.can:527 +["Nil"] = function() -- ./compiler/lua53.can:534 +return "nil" -- ./compiler/lua53.can:535 +end, -- ./compiler/lua53.can:535 +["Dots"] = function() -- ./compiler/lua53.can:538 +return "..." -- ./compiler/lua53.can:539 +end, -- ./compiler/lua53.can:539 +["Boolean"] = function(t) -- ./compiler/lua53.can:542 +return tostring(t[1]) -- ./compiler/lua53.can:543 +end, -- ./compiler/lua53.can:543 +["Number"] = function(t) -- ./compiler/lua53.can:546 +return tostring(t[1]) -- ./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 +["String"] = function(t) -- ./compiler/lua53.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 +end, -- ./compiler/lua53.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 +local r = "(" -- ./compiler/lua53.can:555 +local decl = {} -- ./compiler/lua53.can:556 +if t[1][1] then -- ./compiler/lua53.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 +r = r .. (id) -- ./compiler/lua53.can:563 +else -- ./compiler/lua53.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 +end -- ./compiler/lua53.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 +r = r .. (", " .. id) -- ./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 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +end -- ./compiler/lua53.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 +r = r .. (d .. newline()) -- ./compiler/lua53.can:581 +end -- ./compiler/lua53.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 +end -- ./compiler/lua53.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 +if hasPush then -- ./compiler/lua53.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 +else -- ./compiler/lua53.can:588 +push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 +end -- ./compiler/lua53.can:594 +pop("push") -- ./compiler/lua53.can:596 +return r .. unindent() .. "end" -- ./compiler/lua53.can:597 +end, -- ./compiler/lua53.can:597 +["Function"] = function(t) -- ./compiler/lua53.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 +end, -- ./compiler/lua53.can:600 +["Pair"] = function(t) -- ./compiler/lua53.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 +end, -- ./compiler/lua53.can:604 +["Table"] = function(t) -- ./compiler/lua53.can:606 +if # t == 0 then -- ./compiler/lua53.can:607 +return "{}" -- ./compiler/lua53.can:608 +elseif # t == 1 then -- ./compiler/lua53.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 +else -- ./compiler/lua53.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 +end -- ./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 +["TableCompr"] = function(t) -- ./compiler/lua53.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 +end, -- ./compiler/lua53.can:617 +["Op"] = function(t) -- ./compiler/lua53.can:620 +local r -- ./compiler/lua53.can:621 +if # t == 2 then -- ./compiler/lua53.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 +else -- ./compiler/lua53.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 +end -- ./compiler/lua53.can:626 +else -- ./compiler/lua53.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 +else -- ./compiler/lua53.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./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:632 +return r -- ./compiler/lua53.can:635 +end, -- ./compiler/lua53.can:635 +["Paren"] = function(t) -- ./compiler/lua53.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 +end, -- ./compiler/lua53.can:639 +["MethodStub"] = function(t) -- ./compiler/lua53.can:642 +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:648 +end, -- ./compiler/lua53.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 +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:658 +end, -- ./compiler/lua53.can:658 +["LetExpr"] = function(t) -- ./compiler/lua53.can:665 +return lua(t[1][1]) -- ./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 +["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 +local r = "(function()" .. indent() -- ./compiler/lua53.can:672 +if hasPush then -- ./compiler/lua53.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 +else -- ./compiler/lua53.can:674 +push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 +if hasPush then -- ./compiler/lua53.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 +end -- ./compiler/lua53.can:680 +pop("push") -- ./compiler/lua53.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 +return r -- ./compiler/lua53.can:684 +end, -- ./compiler/lua53.can:684 +["DoExpr"] = function(t) -- ./compiler/lua53.can:687 +if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +t[# t]["tag"] = "Return" -- ./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 +return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 +end, -- ./compiler/lua53.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 +end, -- ./compiler/lua53.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 +end, -- ./compiler/lua53.can:699 +["IfExpr"] = function(t) -- ./compiler/lua53.can:702 +for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +local block = t[i] -- ./compiler/lua53.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +end -- ./compiler/lua53.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 +end, -- ./compiler/lua53.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 +end, -- ./compiler/lua53.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 +end, -- ./compiler/lua53.can:717 +["Call"] = function(t) -- ./compiler/lua53.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 +elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 +else -- ./compiler/lua53.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 +end -- ./compiler/lua53.can:730 +else -- ./compiler/lua53.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 +end -- ./compiler/lua53.can:733 +end, -- ./compiler/lua53.can:733 +["SafeCall"] = function(t) -- ./compiler/lua53.can:737 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 +else -- ./compiler/lua53.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 +end -- ./compiler/lua53.can:741 +end, -- ./compiler/lua53.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 +if start == nil then start = 1 end -- ./compiler/lua53.can:746 +local r -- ./compiler/lua53.can:747 +if t[start] then -- ./compiler/lua53.can:748 +r = lua(t[start]) -- ./compiler/lua53.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 +end -- ./compiler/lua53.can:751 +else -- ./compiler/lua53.can:751 +r = "" -- ./compiler/lua53.can:754 +end -- ./compiler/lua53.can:754 +return r -- ./compiler/lua53.can:756 +end, -- ./compiler/lua53.can:756 +["Id"] = function(t) -- ./compiler/lua53.can:759 +return t[1] -- ./compiler/lua53.can:760 +end, -- ./compiler/lua53.can:760 +["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 +if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +return t["id"] -- ./compiler/lua53.can:765 +else -- ./compiler/lua53.can:765 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 +local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 +for j = 1, # t, 1 do -- ./compiler/lua53.can:769 +table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 +end -- ./compiler/lua53.can:770 +table["insert"](d, vars) -- ./compiler/lua53.can:772 +t["id"] = vars["id"] -- ./compiler/lua53.can:773 +return vars["id"] -- ./compiler/lua53.can:774 +end -- ./compiler/lua53.can:774 +end, -- ./compiler/lua53.can:774 +["Index"] = function(t) -- ./compiler/lua53.can:778 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 +else -- ./compiler/lua53.can:780 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 +end -- ./compiler/lua53.can:782 +end, -- ./compiler/lua53.can:782 +["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 +if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 +local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 +table["insert"](l, 1, t) -- ./compiler/lua53.can:790 +t = t[1] -- ./compiler/lua53.can:791 +end -- ./compiler/lua53.can:791 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +for _, e in ipairs(l) do -- ./compiler/lua53.can:794 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 +if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 +else -- ./compiler/lua53.can:797 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +end -- ./compiler/lua53.can:799 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 +return r -- ./compiler/lua53.can:803 +else -- ./compiler/lua53.can:803 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 +end -- ./compiler/lua53.can:805 +end, -- ./compiler/lua53.can:805 +["_opid"] = { -- ./compiler/lua53.can:810 +["add"] = "+", -- ./compiler/lua53.can:811 +["sub"] = "-", -- ./compiler/lua53.can:811 +["mul"] = "*", -- ./compiler/lua53.can:811 +["div"] = "/", -- ./compiler/lua53.can:811 +["idiv"] = "//", -- ./compiler/lua53.can:812 +["mod"] = "%", -- ./compiler/lua53.can:812 +["pow"] = "^", -- ./compiler/lua53.can:812 +["concat"] = "..", -- ./compiler/lua53.can:812 +["band"] = "&", -- ./compiler/lua53.can:813 +["bor"] = "|", -- ./compiler/lua53.can:813 +["bxor"] = "~", -- ./compiler/lua53.can:813 +["shl"] = "<<", -- ./compiler/lua53.can:813 +["shr"] = ">>", -- ./compiler/lua53.can:813 +["eq"] = "==", -- ./compiler/lua53.can:814 +["ne"] = "~=", -- ./compiler/lua53.can:814 +["lt"] = "<", -- ./compiler/lua53.can:814 +["gt"] = ">", -- ./compiler/lua53.can:814 +["le"] = "<=", -- ./compiler/lua53.can:814 +["ge"] = ">=", -- ./compiler/lua53.can:814 +["and"] = "and", -- ./compiler/lua53.can:815 +["or"] = "or", -- ./compiler/lua53.can:815 +["unm"] = "-", -- ./compiler/lua53.can:815 +["len"] = "#", -- ./compiler/lua53.can:815 +["bnot"] = "~", -- ./compiler/lua53.can:815 +["not"] = "not" -- ./compiler/lua53.can:815 +} -- ./compiler/lua53.can:815 +}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 +end }) -- ./compiler/lua53.can:819 +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 @@ -2320,11 +2782,11 @@ 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 +local code = lua(ast) .. newline() -- ./compiler/lua53.can:825 +return requireStr .. code -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +end -- ./compiler/lua53.can:826 +local lua53 = _() or lua53 -- ./compiler/lua53.can:831 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 @@ -2753,158 +3215,160 @@ 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 -end -- ./lib/lua-parser/validator.lua:315 -return true -- ./lib/lua-parser/validator.lua:317 +elseif tag == "DestructuringId" then -- ./lib/lua-parser/validator.lua:307 +return traverse_table(env, var) -- ./lib/lua-parser/validator.lua:308 +else -- ./lib/lua-parser/validator.lua:308 +error("expecting a variable, but got a " .. tag) -- ./lib/lua-parser/validator.lua:310 +end -- ./lib/lua-parser/validator.lua:310 +end -- ./lib/lua-parser/validator.lua:310 +traverse_varlist = function(env, varlist) -- ./lib/lua-parser/validator.lua:314 +for k, v in ipairs(varlist) do -- ./lib/lua-parser/validator.lua:315 +local status, msg = traverse_var(env, v) -- ./lib/lua-parser/validator.lua:316 +if not status then -- ./lib/lua-parser/validator.lua:317 +return status, msg -- ./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 +end -- ./lib/lua-parser/validator.lua:317 +return true -- ./lib/lua-parser/validator.lua:319 +end -- ./lib/lua-parser/validator.lua:319 +local function traverse_methodstub(env, var) -- ./lib/lua-parser/validator.lua:322 +local status, msg = traverse_exp(env, var[1]) -- ./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 -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 +status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:325 +if not status then -- ./lib/lua-parser/validator.lua:326 +return status, msg -- ./lib/lua-parser/validator.lua:326 +end -- ./lib/lua-parser/validator.lua:326 +return true -- ./lib/lua-parser/validator.lua:327 +end -- ./lib/lua-parser/validator.lua:327 +local function traverse_safeindex(env, var) -- ./lib/lua-parser/validator.lua:330 +local status, msg = traverse_exp(env, var[1]) -- ./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 +status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:333 +if not status then -- ./lib/lua-parser/validator.lua:334 +return status, msg -- ./lib/lua-parser/validator.lua:334 +end -- ./lib/lua-parser/validator.lua:334 +return true -- ./lib/lua-parser/validator.lua:335 +end -- ./lib/lua-parser/validator.lua:335 +traverse_exp = function(env, exp) -- ./lib/lua-parser/validator.lua:338 +local tag = exp["tag"] -- ./lib/lua-parser/validator.lua:339 +if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- `String{ } -- ./lib/lua-parser/validator.lua:343 +return true -- ./lib/lua-parser/validator.lua:344 +elseif tag == "Dots" then -- ./lib/lua-parser/validator.lua:345 +return traverse_vararg(env, exp) -- ./lib/lua-parser/validator.lua:346 +elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } -- ./lib/lua-parser/validator.lua:347 +return traverse_function(env, exp) -- ./lib/lua-parser/validator.lua:348 +elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } -- ./lib/lua-parser/validator.lua:349 +return traverse_table(env, exp) -- ./lib/lua-parser/validator.lua:350 +elseif tag == "Op" then -- `Op{ opid expr expr? } -- ./lib/lua-parser/validator.lua:351 +return traverse_op(env, exp) -- ./lib/lua-parser/validator.lua:352 +elseif tag == "Paren" then -- `Paren{ expr } -- ./lib/lua-parser/validator.lua:353 +return traverse_paren(env, exp) -- ./lib/lua-parser/validator.lua:354 +elseif tag == "Call" or tag == "SafeCall" then -- `(Safe)Call{ expr expr* } -- ./lib/lua-parser/validator.lua:355 +return traverse_call(env, exp) -- ./lib/lua-parser/validator.lua:356 +elseif tag == "Id" or tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:358 +return traverse_var(env, exp) -- ./lib/lua-parser/validator.lua:359 +elseif tag == "SafeIndex" then -- `SafeIndex{ expr expr } -- ./lib/lua-parser/validator.lua:360 +return traverse_safeindex(env, exp) -- ./lib/lua-parser/validator.lua:361 +elseif tag == "TableCompr" then -- `TableCompr{ block } -- ./lib/lua-parser/validator.lua:362 +return traverse_tablecompr(env, exp) -- ./lib/lua-parser/validator.lua:363 +elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- `(Safe)MethodStub{ expr expr } -- ./lib/lua-parser/validator.lua:364 +return traverse_methodstub(env, exp) -- ./lib/lua-parser/validator.lua:365 +elseif tag:match("Expr$") then -- `StatExpr{ ... } -- ./lib/lua-parser/validator.lua:366 +return traverse_statexpr(env, exp) -- ./lib/lua-parser/validator.lua:367 +else -- ./lib/lua-parser/validator.lua:367 +error("expecting an expression, but got a " .. tag) -- ./lib/lua-parser/validator.lua:369 +end -- ./lib/lua-parser/validator.lua:369 +end -- ./lib/lua-parser/validator.lua:369 +traverse_explist = function(env, explist) -- ./lib/lua-parser/validator.lua:373 +for k, v in ipairs(explist) do -- ./lib/lua-parser/validator.lua:374 +local status, msg = traverse_exp(env, v) -- ./lib/lua-parser/validator.lua:375 +if not status then -- ./lib/lua-parser/validator.lua:376 +return status, msg -- ./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 +end -- ./lib/lua-parser/validator.lua:376 +return true -- ./lib/lua-parser/validator.lua:378 +end -- ./lib/lua-parser/validator.lua:378 +traverse_stm = function(env, stm) -- ./lib/lua-parser/validator.lua:381 +local tag = stm["tag"] -- ./lib/lua-parser/validator.lua:382 +if tag == "Do" then -- `Do{ stat* } -- ./lib/lua-parser/validator.lua:383 +return traverse_block(env, stm) -- ./lib/lua-parser/validator.lua:384 +elseif tag == "Set" then -- `Set{ {lhs+} (opid? = opid?)? {expr+} } -- ./lib/lua-parser/validator.lua:385 +return traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:386 +elseif tag == "While" then -- `While{ expr block } -- ./lib/lua-parser/validator.lua:387 +return traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:388 +elseif tag == "Repeat" then -- `Repeat{ block expr } -- ./lib/lua-parser/validator.lua:389 +return traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:390 +elseif tag == "If" then -- `If{ (expr block)+ block? } -- ./lib/lua-parser/validator.lua:391 +return traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:392 +elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } -- ./lib/lua-parser/validator.lua:393 +return traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:394 +elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } -- ./lib/lua-parser/validator.lua:395 +return traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:396 +elseif tag == "Local" or tag == "Let" then -- `Let{ {ident+} {expr+}? } -- ./lib/lua-parser/validator.lua:398 +return traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:399 +elseif tag == "Localrec" then -- `Localrec{ ident expr } -- ./lib/lua-parser/validator.lua:400 +return traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:401 +elseif tag == "Goto" then -- `Goto{ } -- ./lib/lua-parser/validator.lua:402 +return traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:403 +elseif tag == "Label" then -- `Label{ } -- ./lib/lua-parser/validator.lua:404 +return traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:405 +elseif tag == "Return" then -- `Return{ * } -- ./lib/lua-parser/validator.lua:406 +return traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:407 +elseif tag == "Break" then -- ./lib/lua-parser/validator.lua:408 +return traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:409 +elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/validator.lua:410 +return traverse_call(env, stm) -- ./lib/lua-parser/validator.lua:411 +elseif tag == "Continue" then -- ./lib/lua-parser/validator.lua:412 +return traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:413 +elseif tag == "Push" then -- `Push{ * } -- ./lib/lua-parser/validator.lua:414 +return traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:415 +else -- ./lib/lua-parser/validator.lua:415 +error("expecting a statement, but got a " .. tag) -- ./lib/lua-parser/validator.lua:417 +end -- ./lib/lua-parser/validator.lua:417 +end -- ./lib/lua-parser/validator.lua:417 +traverse_block = function(env, block) -- ./lib/lua-parser/validator.lua:421 +local l = {} -- ./lib/lua-parser/validator.lua:422 +new_scope(env) -- ./lib/lua-parser/validator.lua:423 +for k, v in ipairs(block) do -- ./lib/lua-parser/validator.lua:424 +local status, msg = traverse_stm(env, v) -- ./lib/lua-parser/validator.lua:425 +if not status then -- ./lib/lua-parser/validator.lua:426 +return status, msg -- ./lib/lua-parser/validator.lua:426 +end -- ./lib/lua-parser/validator.lua:426 +end -- ./lib/lua-parser/validator.lua:426 +end_scope(env) -- ./lib/lua-parser/validator.lua:428 +return true -- ./lib/lua-parser/validator.lua:429 +end -- ./lib/lua-parser/validator.lua:429 +local function traverse(ast, errorinfo) -- ./lib/lua-parser/validator.lua:433 +assert(type(ast) == "table") -- ./lib/lua-parser/validator.lua:434 +assert(type(errorinfo) == "table") -- ./lib/lua-parser/validator.lua:435 +local env = { -- ./lib/lua-parser/validator.lua:436 +["errorinfo"] = errorinfo, -- ./lib/lua-parser/validator.lua:436 +["function"] = {} -- ./lib/lua-parser/validator.lua:436 +} -- ./lib/lua-parser/validator.lua:436 +new_function(env) -- ./lib/lua-parser/validator.lua:437 +set_vararg(env, true) -- ./lib/lua-parser/validator.lua:438 +local status, msg = traverse_block(env, ast) -- ./lib/lua-parser/validator.lua:439 +if not status then -- ./lib/lua-parser/validator.lua:440 +return status, msg -- ./lib/lua-parser/validator.lua:440 +end -- ./lib/lua-parser/validator.lua:440 +end_function(env) -- ./lib/lua-parser/validator.lua:441 +status, msg = verify_pending_gotos(env) -- ./lib/lua-parser/validator.lua:442 +if not status then -- ./lib/lua-parser/validator.lua:443 +return status, msg -- ./lib/lua-parser/validator.lua:443 +end -- ./lib/lua-parser/validator.lua:443 +return ast -- ./lib/lua-parser/validator.lua:444 +end -- ./lib/lua-parser/validator.lua:444 +return { -- ./lib/lua-parser/validator.lua:447 +["validate"] = traverse, -- ./lib/lua-parser/validator.lua:447 +["syntaxerror"] = syntaxerror -- ./lib/lua-parser/validator.lua:447 +} -- ./lib/lua-parser/validator.lua:447 +end -- ./lib/lua-parser/validator.lua:447 +local validator = _() or validator -- ./lib/lua-parser/validator.lua:451 +package["loaded"]["lib.lua-parser.validator"] = validator or true -- ./lib/lua-parser/validator.lua:452 +local function _() -- ./lib/lua-parser/validator.lua:455 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 @@ -3505,504 +3969,520 @@ local labels = { -- ./lib/lua-parser/parser.lua:88 "expected ']' to close the table key" -- ./lib/lua-parser/parser.lua:165 }, -- ./lib/lua-parser/parser.lua:165 { -- ./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 +"ErrCBraceDestructuring", -- ./lib/lua-parser/parser.lua:167 +"expected '}' to close the destructuring variable list" -- ./lib/lua-parser/parser.lua:167 }, -- ./lib/lua-parser/parser.lua:167 +{ -- ./lib/lua-parser/parser.lua:168 +"ErrDestructuringEqField", -- ./lib/lua-parser/parser.lua:168 +"expected '=' after the table key in destructuring variable list" -- ./lib/lua-parser/parser.lua:168 +}, -- ./lib/lua-parser/parser.lua:168 { -- ./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 +"ErrDestructuringExprField", -- ./lib/lua-parser/parser.lua:169 +"expected an identifier after '=' in destructuring variable list" -- ./lib/lua-parser/parser.lua:169 }, -- ./lib/lua-parser/parser.lua:169 -{ -- ./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 -"ErrDigitExpo", -- ./lib/lua-parser/parser.lua:171 -"expected one or more digits for the exponent" -- ./lib/lua-parser/parser.lua:171 +"ErrCBracketTableCompr", -- ./lib/lua-parser/parser.lua:171 +"expected ']' to close the table comprehension" -- ./lib/lua-parser/parser.lua:171 }, -- ./lib/lua-parser/parser.lua:171 { -- ./lib/lua-parser/parser.lua:173 -"ErrQuote", -- ./lib/lua-parser/parser.lua:173 -"unclosed string" -- ./lib/lua-parser/parser.lua:173 +"ErrDigitHex", -- ./lib/lua-parser/parser.lua:173 +"expected one or more hexadecimal digits after '0x'" -- ./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 +"ErrDigitDeci", -- ./lib/lua-parser/parser.lua:174 +"expected one or more digits after the decimal point" -- ./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 +"ErrDigitExpo", -- ./lib/lua-parser/parser.lua:175 +"expected one or more digits for the exponent" -- ./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 +"ErrQuote", -- ./lib/lua-parser/parser.lua:177 +"unclosed string" -- ./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 +"ErrHexEsc", -- ./lib/lua-parser/parser.lua:178 +"expected exactly two hexadecimal digits after '\\x'" -- ./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 +"ErrOBraceUEsc", -- ./lib/lua-parser/parser.lua:179 +"expected '{' after '\\u'" -- ./lib/lua-parser/parser.lua:179 +}, -- ./lib/lua-parser/parser.lua:179 +{ -- ./lib/lua-parser/parser.lua:180 +"ErrDigitUEsc", -- ./lib/lua-parser/parser.lua:180 +"expected one or more hexadecimal digits for the UTF-8 code point" -- ./lib/lua-parser/parser.lua:180 +}, -- ./lib/lua-parser/parser.lua:180 +{ -- ./lib/lua-parser/parser.lua:181 +"ErrCBraceUEsc", -- ./lib/lua-parser/parser.lua:181 +"expected '}' after the code point" -- ./lib/lua-parser/parser.lua:181 +}, -- ./lib/lua-parser/parser.lua:181 +{ -- ./lib/lua-parser/parser.lua:182 +"ErrEscSeq", -- ./lib/lua-parser/parser.lua:182 +"invalid escape sequence" -- ./lib/lua-parser/parser.lua:182 +}, -- ./lib/lua-parser/parser.lua:182 +{ -- ./lib/lua-parser/parser.lua:183 +"ErrCloseLStr", -- ./lib/lua-parser/parser.lua:183 +"unclosed long string" -- ./lib/lua-parser/parser.lua:183 +} -- ./lib/lua-parser/parser.lua:183 +} -- ./lib/lua-parser/parser.lua:183 +local function throw(label) -- ./lib/lua-parser/parser.lua:186 +label = "Err" .. label -- ./lib/lua-parser/parser.lua:187 +for i, labelinfo in ipairs(labels) do -- ./lib/lua-parser/parser.lua:188 +if labelinfo[1] == label then -- ./lib/lua-parser/parser.lua:189 +return T(i) -- ./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:190 +error("Label not found: " .. label) -- ./lib/lua-parser/parser.lua:194 end -- ./lib/lua-parser/parser.lua:194 -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 +local function expect(patt, label) -- ./lib/lua-parser/parser.lua:197 +return patt + throw(label) -- ./lib/lua-parser/parser.lua:198 +end -- ./lib/lua-parser/parser.lua:198 +local function token(patt) -- ./lib/lua-parser/parser.lua:204 +return patt * V("Skip") -- ./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 +local function sym(str) -- ./lib/lua-parser/parser.lua:208 +return token(P(str)) -- ./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 +local function kw(str) -- ./lib/lua-parser/parser.lua:212 +return token(P(str) * - V("IdRest")) -- ./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"] = e["pos"], -- ./lib/lua-parser/parser.lua:217 -[1] = op, -- ./lib/lua-parser/parser.lua:217 -[2] = e -- ./lib/lua-parser/parser.lua:217 -} -- ./lib/lua-parser/parser.lua:217 +local function tagC(tag, patt) -- ./lib/lua-parser/parser.lua:216 +return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./lib/lua-parser/parser.lua:217 end -- ./lib/lua-parser/parser.lua:217 -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 +local function unaryOp(op, e) -- ./lib/lua-parser/parser.lua:220 +return { -- ./lib/lua-parser/parser.lua:221 +["tag"] = "Op", -- ./lib/lua-parser/parser.lua:221 +["pos"] = e["pos"], -- ./lib/lua-parser/parser.lua:221 +[1] = op, -- ./lib/lua-parser/parser.lua:221 +[2] = e -- ./lib/lua-parser/parser.lua:221 +} -- ./lib/lua-parser/parser.lua:221 +end -- ./lib/lua-parser/parser.lua:221 +local function binaryOp(e1, op, e2) -- ./lib/lua-parser/parser.lua:224 +if not op then -- ./lib/lua-parser/parser.lua:225 +return e1 -- ./lib/lua-parser/parser.lua:226 +else -- ./lib/lua-parser/parser.lua:226 +return { -- ./lib/lua-parser/parser.lua:228 +["tag"] = "Op", -- ./lib/lua-parser/parser.lua:228 +["pos"] = e1["pos"], -- ./lib/lua-parser/parser.lua:228 +[1] = op, -- ./lib/lua-parser/parser.lua:228 +[2] = e1, -- ./lib/lua-parser/parser.lua:228 +[3] = e2 -- ./lib/lua-parser/parser.lua:228 +} -- ./lib/lua-parser/parser.lua:228 +end -- ./lib/lua-parser/parser.lua:228 +end -- ./lib/lua-parser/parser.lua:228 +local function sepBy(patt, sep, label) -- ./lib/lua-parser/parser.lua:232 +if label then -- ./lib/lua-parser/parser.lua:233 +return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./lib/lua-parser/parser.lua:234 +else -- ./lib/lua-parser/parser.lua:234 +return patt * Cg(sep * patt) ^ 0 -- ./lib/lua-parser/parser.lua:236 +end -- ./lib/lua-parser/parser.lua:236 +end -- ./lib/lua-parser/parser.lua:236 +local function chainOp(patt, sep, label) -- ./lib/lua-parser/parser.lua:240 +return Cf(sepBy(patt, sep, label), binaryOp) -- ./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 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 +local function commaSep(patt, label) -- ./lib/lua-parser/parser.lua:244 +return sepBy(patt, sym(","), label) -- ./lib/lua-parser/parser.lua:245 +end -- ./lib/lua-parser/parser.lua:245 +local function tagDo(block) -- ./lib/lua-parser/parser.lua:248 +block["tag"] = "Do" -- ./lib/lua-parser/parser.lua:249 +return block -- ./lib/lua-parser/parser.lua:250 end -- ./lib/lua-parser/parser.lua:250 -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 +local function fixFuncStat(func) -- ./lib/lua-parser/parser.lua:253 +if func[1]["is_method"] then -- ./lib/lua-parser/parser.lua:254 +table["insert"](func[2][1], 1, { -- ./lib/lua-parser/parser.lua:254 +["tag"] = "Id", -- ./lib/lua-parser/parser.lua:254 +[1] = "self" -- ./lib/lua-parser/parser.lua:254 +}) -- ./lib/lua-parser/parser.lua:254 +end -- ./lib/lua-parser/parser.lua:254 +func[1] = { func[1] } -- ./lib/lua-parser/parser.lua:255 +func[2] = { func[2] } -- ./lib/lua-parser/parser.lua:256 +return func -- ./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 +local function addDots(params, dots) -- ./lib/lua-parser/parser.lua:260 +if dots then -- ./lib/lua-parser/parser.lua:261 +table["insert"](params, dots) -- ./lib/lua-parser/parser.lua:261 +end -- ./lib/lua-parser/parser.lua:261 +return params -- ./lib/lua-parser/parser.lua:262 end -- ./lib/lua-parser/parser.lua:262 -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 -end -- ./lib/lua-parser/parser.lua:267 -return t -- ./lib/lua-parser/parser.lua:269 -end -- ./lib/lua-parser/parser.lua:269 -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 +local function insertIndex(t, index) -- ./lib/lua-parser/parser.lua:265 +return { -- ./lib/lua-parser/parser.lua:266 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:266 +["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:266 +[1] = t, -- ./lib/lua-parser/parser.lua:266 +[2] = index -- ./lib/lua-parser/parser.lua:266 +} -- ./lib/lua-parser/parser.lua:266 +end -- ./lib/lua-parser/parser.lua:266 +local function markMethod(t, method) -- ./lib/lua-parser/parser.lua:269 +if method then -- ./lib/lua-parser/parser.lua:270 +return { -- ./lib/lua-parser/parser.lua:271 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:271 +["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:271 +["is_method"] = true, -- ./lib/lua-parser/parser.lua:271 +[1] = t, -- ./lib/lua-parser/parser.lua:271 +[2] = method -- ./lib/lua-parser/parser.lua:271 +} -- ./lib/lua-parser/parser.lua:271 +end -- ./lib/lua-parser/parser.lua:271 +return t -- ./lib/lua-parser/parser.lua:273 +end -- ./lib/lua-parser/parser.lua:273 +local function makeSuffixedExpr(t1, t2) -- ./lib/lua-parser/parser.lua:276 +if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./lib/lua-parser/parser.lua:277 +local t = { -- ./lib/lua-parser/parser.lua:278 +["tag"] = t2["tag"], -- ./lib/lua-parser/parser.lua:278 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:278 +[1] = t1 -- ./lib/lua-parser/parser.lua:278 +} -- ./lib/lua-parser/parser.lua:278 +for k, v in ipairs(t2) do -- ./lib/lua-parser/parser.lua:279 +table["insert"](t, v) -- ./lib/lua-parser/parser.lua:280 +end -- ./lib/lua-parser/parser.lua:280 +return t -- ./lib/lua-parser/parser.lua:282 +elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./lib/lua-parser/parser.lua:283 return { -- ./lib/lua-parser/parser.lua:284 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:284 +["tag"] = t2["tag"], -- ./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 -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 -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 -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 +elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./lib/lua-parser/parser.lua:285 +return { -- ./lib/lua-parser/parser.lua:286 +["tag"] = "SafeIndex", -- ./lib/lua-parser/parser.lua:286 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:286 +[1] = t1, -- ./lib/lua-parser/parser.lua:286 +[2] = t2[1] -- ./lib/lua-parser/parser.lua:286 +} -- ./lib/lua-parser/parser.lua:286 +elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./lib/lua-parser/parser.lua:287 +return { -- ./lib/lua-parser/parser.lua:288 +["tag"] = "Index", -- ./lib/lua-parser/parser.lua:288 +["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:288 +[1] = t1, -- ./lib/lua-parser/parser.lua:288 +[2] = t2[1] -- ./lib/lua-parser/parser.lua:288 +} -- ./lib/lua-parser/parser.lua:288 +else -- ./lib/lua-parser/parser.lua:288 +error("unexpected tag in suffixed expression") -- ./lib/lua-parser/parser.lua:290 +end -- ./lib/lua-parser/parser.lua:290 +end -- ./lib/lua-parser/parser.lua:290 +local function fixShortFunc(t) -- ./lib/lua-parser/parser.lua:294 +if t[1] == ":" then -- self method -- ./lib/lua-parser/parser.lua:295 +table["insert"](t[2], 1, { -- ./lib/lua-parser/parser.lua:296 +["tag"] = "Id", -- ./lib/lua-parser/parser.lua:296 +"self" -- ./lib/lua-parser/parser.lua:296 +}) -- ./lib/lua-parser/parser.lua:296 +table["remove"](t, 1) -- ./lib/lua-parser/parser.lua:297 +t["is_method"] = true -- ./lib/lua-parser/parser.lua:298 +end -- ./lib/lua-parser/parser.lua:298 +t["is_short"] = true -- ./lib/lua-parser/parser.lua:300 +return t -- ./lib/lua-parser/parser.lua:301 +end -- ./lib/lua-parser/parser.lua:301 +local function statToExpr(t) -- tag a StatExpr -- ./lib/lua-parser/parser.lua:304 +t["tag"] = t["tag"] .. "Expr" -- ./lib/lua-parser/parser.lua:305 +return t -- ./lib/lua-parser/parser.lua:306 +end -- ./lib/lua-parser/parser.lua:306 +local function fixStructure(t) -- fix the AST structure if needed -- ./lib/lua-parser/parser.lua:309 +local i = 1 -- ./lib/lua-parser/parser.lua:310 +while i <= # t do -- ./lib/lua-parser/parser.lua:311 +if type(t[i]) == "table" then -- ./lib/lua-parser/parser.lua:312 +fixStructure(t[i]) -- ./lib/lua-parser/parser.lua:313 +for j = # t[i], 1, - 1 do -- ./lib/lua-parser/parser.lua:314 +local stat = t[i][j] -- ./lib/lua-parser/parser.lua:315 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./lib/lua-parser/parser.lua:316 +table["remove"](t[i], j) -- ./lib/lua-parser/parser.lua:317 +table["insert"](t, i + 1, stat) -- ./lib/lua-parser/parser.lua:318 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./lib/lua-parser/parser.lua:319 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./lib/lua-parser/parser.lua:320 +end -- ./lib/lua-parser/parser.lua:320 +end -- ./lib/lua-parser/parser.lua:320 +end -- ./lib/lua-parser/parser.lua:320 +end -- ./lib/lua-parser/parser.lua:320 +i = i + 1 -- ./lib/lua-parser/parser.lua:325 +end -- ./lib/lua-parser/parser.lua:325 +return t -- ./lib/lua-parser/parser.lua:327 +end -- ./lib/lua-parser/parser.lua:327 +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:330 +for i, stat in ipairs(block) do -- ./lib/lua-parser/parser.lua:331 +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:333 +local exprlist -- ./lib/lua-parser/parser.lua:334 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./lib/lua-parser/parser.lua:336 +exprlist = stat[# stat] -- ./lib/lua-parser/parser.lua:337 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./lib/lua-parser/parser.lua:338 +exprlist = stat -- ./lib/lua-parser/parser.lua:339 +end -- ./lib/lua-parser/parser.lua:339 +local last = exprlist[# exprlist] -- last value in ExprList -- ./lib/lua-parser/parser.lua:342 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./lib/lua-parser/parser.lua:346 +local p = i -- ./lib/lua-parser/parser.lua:347 +for j, fstat in ipairs(last[2]) do -- ./lib/lua-parser/parser.lua:348 +p = i + j -- ./lib/lua-parser/parser.lua:349 +table["insert"](block, p, fstat) -- copy stats from func body to block -- ./lib/lua-parser/parser.lua:350 +if stat["move_up_block"] then -- extracted stats inherit move_up_block from statement -- ./lib/lua-parser/parser.lua:352 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./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 -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 +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:356 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:357 +end -- ./lib/lua-parser/parser.lua:357 +end -- ./lib/lua-parser/parser.lua:357 +exprlist[# exprlist] = last[1] -- replace func with paren and expressions -- ./lib/lua-parser/parser.lua:361 +exprlist[# exprlist]["tag"] = "Paren" -- ./lib/lua-parser/parser.lua:362 +if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:364 +for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:365 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:366 +end -- ./lib/lua-parser/parser.lua:366 +end -- ./lib/lua-parser/parser.lua:366 +return block, i -- ./lib/lua-parser/parser.lua:370 +elseif last["tag"]:match("Expr$") then -- ./lib/lua-parser/parser.lua:373 +local r = searchEndRec({ last }) -- ./lib/lua-parser/parser.lua:374 +if r then -- ./lib/lua-parser/parser.lua:375 +for j = 2, # r, 1 do -- ./lib/lua-parser/parser.lua:376 +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:377 +end -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:377 +return block, i -- ./lib/lua-parser/parser.lua:379 +end -- ./lib/lua-parser/parser.lua:379 +elseif last["tag"] == "Function" then -- ./lib/lua-parser/parser.lua:381 +local r = searchEndRec(last[2]) -- ./lib/lua-parser/parser.lua:382 +if r then -- ./lib/lua-parser/parser.lua:383 +return block, i -- ./lib/lua-parser/parser.lua:384 +end -- ./lib/lua-parser/parser.lua:384 +end -- ./lib/lua-parser/parser.lua:384 +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:389 +local blocks -- ./lib/lua-parser/parser.lua:390 +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:392 +blocks = stat -- ./lib/lua-parser/parser.lua:393 +elseif stat["tag"]:match("^Do") then -- ./lib/lua-parser/parser.lua:394 +blocks = { stat } -- ./lib/lua-parser/parser.lua:395 +end -- ./lib/lua-parser/parser.lua:395 +for _, iblock in ipairs(blocks) do -- ./lib/lua-parser/parser.lua:398 +if iblock["tag"] == "Block" then -- blocks -- ./lib/lua-parser/parser.lua:399 +local oldLen = # iblock -- ./lib/lua-parser/parser.lua:400 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./lib/lua-parser/parser.lua:401 +if newiBlock then -- if end in the block -- ./lib/lua-parser/parser.lua:402 +local p = i -- ./lib/lua-parser/parser.lua:403 +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:404 +p = p + 1 -- ./lib/lua-parser/parser.lua:405 +table["insert"](block, p, iblock[j]) -- ./lib/lua-parser/parser.lua:406 +iblock[j] = nil -- ./lib/lua-parser/parser.lua:407 +end -- ./lib/lua-parser/parser.lua:407 +if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:410 +for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:411 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./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 -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 +return block, i -- ./lib/lua-parser/parser.lua:416 +end -- ./lib/lua-parser/parser.lua:416 +end -- ./lib/lua-parser/parser.lua:416 +end -- ./lib/lua-parser/parser.lua:416 +end -- ./lib/lua-parser/parser.lua:416 +end -- ./lib/lua-parser/parser.lua:416 +return nil -- ./lib/lua-parser/parser.lua:422 +end -- ./lib/lua-parser/parser.lua:422 +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:425 +local r = searchEndRec(fixStructure(t)) -- ./lib/lua-parser/parser.lua:426 +if not r then -- ./lib/lua-parser/parser.lua:427 +return false -- ./lib/lua-parser/parser.lua:428 +end -- ./lib/lua-parser/parser.lua:428 +return true, r -- ./lib/lua-parser/parser.lua:430 +end -- ./lib/lua-parser/parser.lua:430 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match -- ./lib/lua-parser/parser.lua:433 +if canFollow then -- ./lib/lua-parser/parser.lua:434 +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:437 +else -- ./lib/lua-parser/parser.lua:437 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:441 +end -- ./lib/lua-parser/parser.lua:441 +end -- ./lib/lua-parser/parser.lua:441 +local function expectBlockWithEnd(label) -- can't work *optionnaly* with SingleStat unfortunatly -- ./lib/lua-parser/parser.lua:445 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./lib/lua-parser/parser.lua:447 +end -- ./lib/lua-parser/parser.lua:447 +local function maybeBlockWithEnd() -- same as above but don't error if it doesn't match -- ./lib/lua-parser/parser.lua:450 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./lib/lua-parser/parser.lua:452 +end -- ./lib/lua-parser/parser.lua:452 +local stacks = { ["lexpr"] = {} } -- ./lib/lua-parser/parser.lua:456 +local function push(f) -- ./lib/lua-parser/parser.lua:458 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:459 +table["insert"](stacks[f], true) -- ./lib/lua-parser/parser.lua:460 +return true -- ./lib/lua-parser/parser.lua:461 +end) -- ./lib/lua-parser/parser.lua:461 +end -- ./lib/lua-parser/parser.lua:461 +local function pop(f) -- ./lib/lua-parser/parser.lua:464 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:465 +table["remove"](stacks[f]) -- ./lib/lua-parser/parser.lua:466 +return true -- ./lib/lua-parser/parser.lua:467 +end) -- ./lib/lua-parser/parser.lua:467 +end -- ./lib/lua-parser/parser.lua:467 +local function when(f) -- ./lib/lua-parser/parser.lua:470 +return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:471 +return # stacks[f] > 0 -- ./lib/lua-parser/parser.lua:472 +end) -- ./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 +local function set(f, patt) -- patt *must* succeed (or throw an error) to preserve stack integrity -- ./lib/lua-parser/parser.lua:475 +return push(f) * patt * pop(f) -- ./lib/lua-parser/parser.lua:476 +end -- ./lib/lua-parser/parser.lua:476 +local G = { -- ./lib/lua-parser/parser.lua:480 +V("Lua"), -- ./lib/lua-parser/parser.lua:480 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./lib/lua-parser/parser.lua:481 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 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 +")) ^ 0, -- ./lib/lua-parser/parser.lua:482 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./lib/lua-parser/parser.lua:484 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./lib/lua-parser/parser.lua:490 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./lib/lua-parser/parser.lua:491 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./lib/lua-parser/parser.lua:493 +t["is_singlestatblock"] = true -- ./lib/lua-parser/parser.lua:493 +return t -- ./lib/lua-parser/parser.lua:493 +end, -- ./lib/lua-parser/parser.lua:493 +["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:494 +["IfStat"] = tagC("If", V("IfPart")), -- ./lib/lua-parser/parser.lua:496 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:497 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:498 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./lib/lua-parser/parser.lua:499 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./lib/lua-parser/parser.lua:501 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./lib/lua-parser/parser.lua:502 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./lib/lua-parser/parser.lua:503 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./lib/lua-parser/parser.lua:504 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./lib/lua-parser/parser.lua:506 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./lib/lua-parser/parser.lua:507 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./lib/lua-parser/parser.lua:509 +["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./lib/lua-parser/parser.lua:510 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./lib/lua-parser/parser.lua:511 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./lib/lua-parser/parser.lua:513 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:514 +["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./lib/lua-parser/parser.lua:516 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./lib/lua-parser/parser.lua:518 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./lib/lua-parser/parser.lua:520 +["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./lib/lua-parser/parser.lua:522 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:524 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./lib/lua-parser/parser.lua:526 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./lib/lua-parser/parser.lua:527 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./lib/lua-parser/parser.lua:528 +["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:531 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./lib/lua-parser/parser.lua:533 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./lib/lua-parser/parser.lua:534 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./lib/lua-parser/parser.lua:536 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:538 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:539 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./lib/lua-parser/parser.lua:541 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./lib/lua-parser/parser.lua:542 +["BreakStat"] = tagC("Break", kw("break")), -- ./lib/lua-parser/parser.lua:543 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./lib/lua-parser/parser.lua:544 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:545 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:547 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./lib/lua-parser/parser.lua:548 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./lib/lua-parser/parser.lua:550 +["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./lib/lua-parser/parser.lua:551 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./lib/lua-parser/parser.lua:552 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./lib/lua-parser/parser.lua:553 +["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./lib/lua-parser/parser.lua:555 +["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:556 +["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:558 +["Expr"] = V("OrExpr"), -- ./lib/lua-parser/parser.lua:560 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./lib/lua-parser/parser.lua:561 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./lib/lua-parser/parser.lua:562 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./lib/lua-parser/parser.lua:563 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./lib/lua-parser/parser.lua:564 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./lib/lua-parser/parser.lua:565 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./lib/lua-parser/parser.lua:566 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./lib/lua-parser/parser.lua:567 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:568 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./lib/lua-parser/parser.lua:569 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./lib/lua-parser/parser.lua:570 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./lib/lua-parser/parser.lua:572 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:573 +["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("DestructuringNameList") * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./lib/lua-parser/parser.lua:583 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./lib/lua-parser/parser.lua:585 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:587 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./lib/lua-parser/parser.lua:587 +end), -- ./lib/lua-parser/parser.lua:587 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:588 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./lib/lua-parser/parser.lua:588 +end), -- ./lib/lua-parser/parser.lua:588 +["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:592 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./lib/lua-parser/parser.lua:595 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./lib/lua-parser/parser.lua:596 +["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:600 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./lib/lua-parser/parser.lua:602 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./lib/lua-parser/parser.lua:604 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./lib/lua-parser/parser.lua:605 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./lib/lua-parser/parser.lua:606 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./lib/lua-parser/parser.lua:608 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./lib/lua-parser/parser.lua:611 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./lib/lua-parser/parser.lua:613 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:614 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./lib/lua-parser/parser.lua:616 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:618 +["FieldSep"] = sym(",") + sym(";"), -- ./lib/lua-parser/parser.lua:619 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./lib/lua-parser/parser.lua:621 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./lib/lua-parser/parser.lua:623 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./lib/lua-parser/parser.lua:624 +["StrId"] = tagC("String", V("Name")), -- ./lib/lua-parser/parser.lua:625 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./lib/lua-parser/parser.lua:628 +["Space"] = space ^ 1, -- ./lib/lua-parser/parser.lua:629 +["Comment"] = P("--") * V("LongStr") / function() -- ./lib/lua-parser/parser.lua:630 +return -- ./lib/lua-parser/parser.lua:630 end + P("--") * (P(1) - P("\ -")) ^ 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 +")) ^ 0, -- ./lib/lua-parser/parser.lua:631 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./lib/lua-parser/parser.lua:633 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./lib/lua-parser/parser.lua:634 +["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:638 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./lib/lua-parser/parser.lua:639 +["IdStart"] = alpha + P("_"), -- ./lib/lua-parser/parser.lua:640 +["IdRest"] = alnum + P("_"), -- ./lib/lua-parser/parser.lua:641 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./lib/lua-parser/parser.lua:643 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./lib/lua-parser/parser.lua:644 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./lib/lua-parser/parser.lua:646 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./lib/lua-parser/parser.lua:648 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./lib/lua-parser/parser.lua:649 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:650 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:651 +["Int"] = digit ^ 1, -- ./lib/lua-parser/parser.lua:652 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./lib/lua-parser/parser.lua:654 ["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:643 +"))) ^ 0) * expect(P("'"), "Quote"), -- ./lib/lua-parser/parser.lua:656 ["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: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 +" + 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:686 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./lib/lua-parser/parser.lua:689 +return s -- ./lib/lua-parser/parser.lua:689 +end, -- ./lib/lua-parser/parser.lua:689 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 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 +") ^ - 1, -- ./lib/lua-parser/parser.lua:690 +["Close"] = "]" * C(V("Equals")) * "]", -- ./lib/lua-parser/parser.lua:691 +["Equals"] = P("=") ^ 0, -- ./lib/lua-parser/parser.lua:692 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./lib/lua-parser/parser.lua:693 +return # openEq == # closeEq -- ./lib/lua-parser/parser.lua:693 +end), -- ./lib/lua-parser/parser.lua:693 +["OrOp"] = kw("or") / "or", -- ./lib/lua-parser/parser.lua:695 +["AndOp"] = kw("and") / "and", -- ./lib/lua-parser/parser.lua:696 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./lib/lua-parser/parser.lua:702 +["BOrOp"] = sym("|") / "bor", -- ./lib/lua-parser/parser.lua:703 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./lib/lua-parser/parser.lua:704 +["BAndOp"] = sym("&") / "band", -- ./lib/lua-parser/parser.lua:705 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./lib/lua-parser/parser.lua:707 +["ConcatOp"] = sym("..") / "concat", -- ./lib/lua-parser/parser.lua:708 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./lib/lua-parser/parser.lua:710 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./lib/lua-parser/parser.lua:714 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./lib/lua-parser/parser.lua:718 +["PowOp"] = sym("^") / "pow", -- ./lib/lua-parser/parser.lua:719 +["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:720 +} -- ./lib/lua-parser/parser.lua:720 +local parser = {} -- ./lib/lua-parser/parser.lua:723 +local validator = require("lib.lua-parser.validator") -- ./lib/lua-parser/parser.lua:725 +local validate = validator["validate"] -- ./lib/lua-parser/parser.lua:726 +local syntaxerror = validator["syntaxerror"] -- ./lib/lua-parser/parser.lua:727 +parser["parse"] = function(subject, filename) -- ./lib/lua-parser/parser.lua:729 +local errorinfo = { -- ./lib/lua-parser/parser.lua:730 +["subject"] = subject, -- ./lib/lua-parser/parser.lua:730 +["filename"] = filename -- ./lib/lua-parser/parser.lua:730 +} -- ./lib/lua-parser/parser.lua:730 +lpeg["setmaxstack"](1000) -- ./lib/lua-parser/parser.lua:731 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./lib/lua-parser/parser.lua:732 +if not ast then -- ./lib/lua-parser/parser.lua:733 +local errmsg = labels[label][2] -- ./lib/lua-parser/parser.lua:734 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./lib/lua-parser/parser.lua:735 +end -- ./lib/lua-parser/parser.lua:735 +return validate(ast, errorinfo) -- ./lib/lua-parser/parser.lua:737 +end -- ./lib/lua-parser/parser.lua:737 +return parser -- ./lib/lua-parser/parser.lua:740 +end -- ./lib/lua-parser/parser.lua:740 +local parser = _() or parser -- ./lib/lua-parser/parser.lua:744 +package["loaded"]["lib.lua-parser.parser"] = parser or true -- ./lib/lua-parser/parser.lua:745 +local candran = { ["VERSION"] = "0.11.0" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 ["indentation"] = "", -- candran.can:20 diff --git a/compiler/lua53.can b/compiler/lua53.can index 656ac0e..7e390df 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -14,7 +14,7 @@ return function(code, ast, options) 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") + local source, line = sub:sub(1, sub:find("\n")):match(".*%-%- (.-)%:(%d+)\n") if source and line then lastSource = source @@ -42,15 +42,31 @@ return function(code, ast, options) return newline() end - --- Module management - local required = {} -- { ["module"] = true, ... } - local requireStr = "" - -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". - local function addRequire(mod, name, field) - if not required[mod] then - requireStr ..= "local "..options.variablePrefix..name..(" = require(%q)"):format(mod)..(field and "."..field or "")..options.newline - required[mod] = true - end + --- State stacks + -- Used for context-sensitive syntax. + local states = { + push = {}, -- push stack variable names + destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} + scope = {} -- list of variables defined in the current scope + } + -- Push a new value on top of the stack "name". Returns an empty string for chaining. + local function push(name, state) + table.insert(states[name], state) + return "" + end + -- Remove the value on top of the stack "name". Returns an empty string for chaining. + local function pop(name) + table.remove(states[name]) + return "" + end + -- Set the value on top of the stack "name". Returns an empty string for chaining. + local function set(name, state) + states[name][#states[name]] = state + return "" + end + -- Returns the value on top of the stack "name". + local function peek(name) + return states[name][#states[name]] end --- Variable management @@ -59,6 +75,26 @@ return function(code, ast, options) return options.variablePrefix..name end + -- Returns the prefixed temporary variable name. + local function tmp() + local scope = peek("scope") + local var = "%s_%s":format(options.variablePrefix, #scope) + table.insert(scope, var) + return var + end + + --- Module management + local required = {} -- { ["full require expression"] = true, ... } + local requireStr = "" + -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". + local function addRequire(mod, name, field) + local req = "require(%q)%s":format(mod, field and "."..field or "") + if not required[req] then + requireStr ..= "local %s = %s%s":format(var(name), req, options.newline) + required[req] = true + end + end + --- AST traversal helpers local loop = { "While", "Repeat", "Fornum", "Forin", "WhileExpr", "RepeatExpr", "FornumExpr", "ForinExpr" } -- loops tags (can contain continue) local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags (can contain push) @@ -132,26 +168,6 @@ return function(code, ast, options) return true end - --- State stacks - -- Used for context-sensitive syntax. - local states = { - push = {} -- push stack variable names - } - -- Push a new value on top of the stack "name". Returns an empty string for chaining. - local function push(name, state) - table.insert(states[name], state) - return "" - end - -- Remove the value on top of the stack "name". Returns an empty string for chaining. - local function pop(name) - table.remove(states[name]) - return "" - end - -- Returns the value on top of the stack "name". - local function peek(name) - return states[name][#states[name]] - end - --- Lua compiler local tags -- Recursively returns the compiled AST Lua code, set "forceTag" to override the tag type and pass additional arguments to the tag constructor if needed. @@ -175,6 +191,43 @@ return function(code, ast, options) local CONTINUE_STOP = () -- at the start of loops using continue return unindent().."end"..newline().."::"..var"continue".."::" end + local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement + local vars = {} + local values = {} + for _, list in ipairs(destructured) do + for _, v in ipairs(list) do + local var, val + if v.tag == "Id" then + var = v + val = { tag = "Index", { tag = "Id", list.id }, { tag = "String", v[1] } } + elseif v.tag == "Pair" then + var = v[2] + val = { tag = "Index", { tag = "Id", list.id }, v[1] } + else + error("unknown destructuring element type: "..tostring(v.tag)) + end + if destructured.rightOp and destructured.leftOp then + val = { tag = "Op", destructured.rightOp, var, { tag = "Op", destructured.leftOp, val, var } } + elseif destructured.rightOp then + val = { tag = "Op", destructured.rightOp, var, val } + elseif destructured.leftOp then + val = { tag = "Op", destructured.leftOp, val, var } + end + table.insert(vars, lua(var)) + table.insert(values, lua(val)) + end + end + if #vars > 0 then + local decl = noLocal and "" or "local " + if newlineAfter then + return decl..table.concat(vars, ", ").." = "..table.concat(values, ", ")..newline() + else + return newline()..decl..table.concat(vars, ", ").." = "..table.concat(values, ", ") + end + else + return "" + end + end --- Tag constructors tags = setmetatable({ @@ -185,7 +238,7 @@ return function(code, ast, options) hasPush.tag = "Return" hasPush = false end - local r = "" + local r = push("scope", {}) if hasPush then r ..= push("push", var"push").."local "..var"push".." = {}"..newline() end @@ -198,7 +251,7 @@ return function(code, ast, options) if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed r ..= newline().."return "..UNPACK(var"push")..pop("push") end - return r + return r..pop("scope") end, -- stat -- @@ -209,28 +262,73 @@ return function(code, ast, options) end, -- Set{ {lhs+} (opid? = opid?)? {expr+} } Set = (t) - if #t == 2 then - return lua(t[1], "_lhs").." = "..lua(t[2], "_lhs") - elseif #t == 3 then - return lua(t[1], "_lhs").." = "..lua(t[3], "_lhs") + -- extract vars and values + local expr = t[#t] + local vars, values = {}, {} + local destructuringVars, destructuringValues = {}, {} + for i, n in ipairs(t[1]) do + if n.tag == "DestructuringId" then + table.insert(destructuringVars, n) + table.insert(destructuringValues, expr[i]) + else + table.insert(vars, n) + table.insert(values, expr[i]) + end + end + -- + if #t == 2 or #t == 3 then + local r = "" + if #vars > 0 then + r = lua(vars, "_lhs").." = "..lua(values, "_lhs") + end + if #destructuringVars > 0 then + local destructured = {} + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r elseif #t == 4 then if t[3] == "=" then - local r = 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") + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Paren", values[1] } }, "Op") + for i=2, math.min(#t[4], #vars), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Paren", values[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) end return r else - local r = 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") + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[3], { tag = "Paren", values[1] }, vars[1] }, "Op") + for i=2, math.min(#t[4], #t[1]), 1 do + r ..= ", "..lua({ t[3], { tag = "Paren", values[i] }, vars[i] }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { leftOp = t[3] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) end return r end else -- You are mad. - local r = 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") + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Op", t[4], { tag = "Paren", values[1] }, vars[1] } }, "Op") + for i=2, math.min(#t[5], #t[1]), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Op", t[4], { tag = "Paren", values[i] }, vars[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2], leftOp = t[4] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) end return r end @@ -344,12 +442,13 @@ return function(code, ast, options) end, -- Forin{ {ident+} {expr+} block } Forin = (t) + local destructured = {} local hasContinue = any(t[3], { "Continue" }, loop) - local r = "for "..lua(t[1], "_lhs").." in "..lua(t[2], "_lhs").." do"..indent() + local r = "for "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring").." in "..lua(t[2], "_lhs").." do"..indent() if hasContinue then r ..= CONTINUE_START() end - r ..= lua(t[3]) + r ..= DESTRUCTURING_ASSIGN(destructured, true)..lua(t[3]) if hasContinue then r ..= CONTINUE_STOP() end @@ -357,15 +456,17 @@ return function(code, ast, options) end, -- Local{ {ident+} {expr+}? } Local = (t) - local r = "local "..lua(t[1], "_lhs") + local destructured = {} + local r = "local "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") if t[2][1] then r ..= " = "..lua(t[2], "_lhs") end - return r + return r..DESTRUCTURING_ASSIGN(destructured) end, -- Let{ {ident+} {expr+}? } Let = (t) - local nameList = lua(t[1], "_lhs") + local destructured = {} + local nameList = push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") local r = "local "..nameList if t[2][1] then if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here @@ -374,7 +475,7 @@ return function(code, ast, options) r ..= newline()..nameList.." = "..lua(t[2], "_lhs") end end - return r + return r..DESTRUCTURING_ASSIGN(destructured) end, -- Localrec{ {ident} {expr} } Localrec = (t) @@ -658,6 +759,21 @@ return function(code, ast, options) Id = (t) return t[1] end, + -- DestructuringId{ Id | Pair+ } + DestructuringId = (t) + if t.id then -- destructing already done before, use parent variable as id + return t.id + else + local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") + local vars = { id = tmp() } + for j=1, #t, 1 do + table.insert(vars, t[j]) + end + table.insert(d, vars) + t.id = vars.id + return vars.id + end + end, -- Index{ expr expr } Index = (t) if t[1].tag == "String" or t[1].tag == "Table" then diff --git a/compiler/luajit.can b/compiler/luajit.can index 79e85be..a4d068b 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -1,4 +1,4 @@ -targetName = "luajit" +targetName = "LuaJIT" UNPACK = (list, i, j) return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" diff --git a/ideas.txt b/ideas.txt index 6c3f6c8..fd8b547 100644 --- a/ideas.txt +++ b/ideas.txt @@ -6,7 +6,7 @@ To be implemented, theese need to: * are invalid vanilla Lua syntax. * are not ambigous with any vanilla Lua syntax. * 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. +* be useful without having to rewrite APIs specifically for Candran. Candran intends to make Lua easier, not replace it. Example rejected ideas: * Python-style function decorators (implemented in Candran 0.1.0): @@ -37,6 +37,7 @@ end local a = new Thing() -> (TODO: define how classes work. May even use ClassCommons) + Not very Lua-ey to impose how to make your classes? * try / except|catch / finally / else / other keywords @@ -48,6 +49,8 @@ finally clean() end +may be doable using if with assignement + pcall + * static type checking local a = externalFunc() -- unknown if a == "hey" then @@ -70,20 +73,26 @@ local b = a[3:5:1] is it actually useful? even in python I rarely use it, apart from extracting a row or column for a matrix (and we don't have >1D arrays in Lua so...) +OR return multiple value instead of a list? + +or list of incices: +local a, b, c = l[1, 2, 3] + +how to handle hash table? +local a, b, c = l.(a, b, c) +or +local a, b, c = l.a, .b, .c + +but +local a, b, c = l[1], [2], [3] +conflicts with table comprehension: change or use .[n]? + +or create some syntax akin to destructuring assignemnts but for numeric indexes: +local [a, b, c] = t + * Destructuring assignment -local pos = { x = 5, y = 12 } -local {x, y} = pos -- x, y = pos.x, pos.y -local {a, b, x = x, y = y} = pos -- x, y = pos.x, pos.y, a = pos[1], b = pos[2] -local {a, b, :x, :y} = pos -- shorthand for the above line. Or .x, .y -local {:x.u} = pos OR {:x:u} OR {.x.u} -- u = pos.x.u -local [x, y] = pos -- x, y = pos[0], pos[1] -local x, y $= pos - -And in implicit assignments: -for i, {x, y} in ipairs(positions) do - -Sounds useful, at least the key-value part. +Allow recursive destructing assignements * String interpolation Delimited by ``: @@ -93,4 +102,7 @@ Also allows multi-line with this maybe? meh * Other potential inspiration -https://www.ruby-lang.org/fr/ +https://www.ruby-lang.org/ + +* Lua 5.4 stuff +const, to-be-closed variables: they're fun but as of now the syntax is awful diff --git a/lib/lua-parser/parser.lua b/lib/lua-parser/parser.lua index e16d959..8864daa 100644 --- a/lib/lua-parser/parser.lua +++ b/lib/lua-parser/parser.lua @@ -59,7 +59,7 @@ apply: `Call{ expr expr* } | `SafeCall{ expr expr* } -lhs: `Id{ } | `Index{ expr expr } +lhs: `Id{ } | `Index{ expr expr } | ˇDestructuringId{ Id | Pair+ } opid: -- includes additional operators from Lua 5.3 and all relational operators 'add' | 'sub' | 'mul' | 'div' @@ -164,6 +164,10 @@ local labels = { { "ErrExprFKey", "expected an expression after '[' for the table key" }, { "ErrCBracketFKey", "expected ']' to close the table key" }, + { "ErrCBraceDestructuring", "expected '}' to close the destructuring variable list" }, + { "ErrDestructuringEqField", "expected '=' after the table key in destructuring variable list" }, + { "ErrDestructuringExprField", "expected an identifier after '=' in destructuring variable list" }, + { "ErrCBracketTableCompr", "expected ']' to close the table comprehension" }, { "ErrDigitHex", "expected one or more hexadecimal digits after '0x'" }, @@ -480,8 +484,9 @@ local G = { V"Lua", Block = tagC("Block", (V"Stat" + -V"BlockEnd" * throw("InvalidStat"))^0 * ((V"RetStat" + V"ImplicitPushStat") * sym(";")^-1)^-1); Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat" + V"LocalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat" + + V"LetStat" + V"FuncCall" + V"Assignment" - + V"LetStat" + V"ContinueStat" + V"PushStat" + + V"ContinueStat" + V"PushStat" + sym(";"); BlockEnd = P"return" + "end" + "elseif" + "else" + "until" + "]" + -1 + V"ImplicitPushStat" + V"Assignment"; @@ -502,17 +507,19 @@ local G = { V"Lua", ForNum = tagC("Fornum", V"Id" * sym("=") * V"NumRange" * V"ForBody"); NumRange = expect(V"Expr", "ExprFor1") * expect(sym(","), "CommaFor") *expect(V"Expr", "ExprFor2") * (sym(",") * expect(V"Expr", "ExprFor3"))^-1; - ForIn = tagC("Forin", V"NameList" * expect(kw("in"), "InFor") * expect(V"ExprList", "EListFor") * V"ForBody"); + ForIn = tagC("Forin", V"DestructuringNameList" * expect(kw("in"), "InFor") * expect(V"ExprList", "EListFor") * V"ForBody"); ForBody = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"); LocalStat = kw("local") * expect(V"LocalFunc" + V"LocalAssign", "DefLocal"); LocalFunc = tagC("Localrec", kw("function") * expect(V"Id", "NameLFunc") * V"FuncBody") / fixFuncStat; - LocalAssign = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))); + LocalAssign = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + + tagC("Local", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); LetStat = kw("let") * expect(V"LetAssign", "DefLet"); - LetAssign = tagC("Let", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))); + LetAssign = tagC("Let", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + + tagC("Let", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); - Assignment = tagC("Set", V"VarList" * V"BinOp"^-1 * (P"=" / "=") * ((V"BinOp" - P"-") + #(P"-" * V"Space") * V"BinOp")^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); + Assignment = tagC("Set", (V"VarList" + V"DestructuringNameList") * V"BinOp"^-1 * (P"=" / "=") * ((V"BinOp" - P"-") + #(P"-" * V"Space") * V"BinOp")^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); FuncStat = tagC("Set", kw("function") * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat; FuncName = Cf(V"Id" * (sym(".") * expect(V"StrId", "NameFunc1"))^0, insertIndex) @@ -541,9 +548,15 @@ local G = { V"Lua", ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList")); NameList = tagC("NameList", commaSep(V"Id")); + DestructuringNameList = tagC("NameList", commaSep(V"DestructuringId")), VarList = tagC("VarList", commaSep(V"VarExpr")); ExprList = tagC("ExpList", commaSep(V"Expr", "ExprList")); + DestructuringId = tagC("DestructuringId", sym("{") * V"DestructuringIdFieldList" * expect(sym("}"), "CBraceDestructuring")) + V"Id", + DestructuringIdFieldList = sepBy(V"DestructuringIdField", V"FieldSep") * V"FieldSep"^-1; + DestructuringIdField = tagC("Pair", V"FieldKey" * expect(sym("="), "DestructuringEqField") * expect(V"Id", "DestructuringExprField")) + + V"Id"; + Expr = V"OrExpr"; OrExpr = chainOp(V"AndExpr", V"OrOp", "OrExpr"); AndExpr = chainOp(V"RelExpr", V"AndOp", "AndExpr"); @@ -564,7 +577,7 @@ local G = { V"Lua", + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V"FuncDef" - + (when("lexpr") * tagC("LetExpr", V"NameList" * sym("=") * -sym("=") * expect(V"ExprList", "EListLAssign"))) + + (when("lexpr") * tagC("LetExpr", V"DestructuringNameList" * sym("=") * -sym("=") * expect(V"ExprList", "EListLAssign"))) + V"ShortFuncDef" + V"SuffixedExpr" + V"StatExpr"; diff --git a/lib/lua-parser/validator.lua b/lib/lua-parser/validator.lua index 2094446..210cc82 100644 --- a/lib/lua-parser/validator.lua +++ b/lib/lua-parser/validator.lua @@ -304,6 +304,8 @@ function traverse_var (env, var) status, msg = traverse_exp(env, var[2]) if not status then return status, msg end return true + elseif tag == "DestructuringId" then + return traverse_table(env, var) else error("expecting a variable, but got a " .. tag) end diff --git a/rockspec/candran-0.10.0-1.rockspec b/rockspec/candran-0.11.0-1.rockspec similarity index 94% rename from rockspec/candran-0.10.0-1.rockspec rename to rockspec/candran-0.11.0-1.rockspec index 31e9cf4..674956a 100644 --- a/rockspec/candran-0.10.0-1.rockspec +++ b/rockspec/candran-0.11.0-1.rockspec @@ -19,12 +19,13 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.10.0" + tag = "v0.11.0" } dependencies = { "lua >= 5.1", - "lpeglabel >= 1.5.0" + "lpeglabel >= 1.5.0", + "linenoise >= 0.9" } build = { diff --git a/test/test.lua b/test/test.lua index e4f16b8..b43603c 100644 --- a/test/test.lua +++ b/test/test.lua @@ -10,6 +10,10 @@ local function test(name, candranCode, expectedResult, options) results[name] = { result = "not finished", message = "no info" } local self = results[name] + -- options + options = options or {} + options.chunkname = name + -- make code local success, code = pcall(candran.make, candranCode, options) if not success then @@ -125,554 +129,554 @@ return a -- Assignement operators test("+=", [[ -local a = 5 -a += 2 -return a + local a = 5 + a += 2 + return a ]], 7) test("-=", [[ -local a = 5 -a -= 2 -return a + local a = 5 + a -= 2 + return a ]], 3) test("*=", [[ -local a = 5 -a *= 2 -return a + local a = 5 + a *= 2 + return a ]], 10) test("/=", [[ -local a = 5 -a /= 2 -return a + local a = 5 + a /= 2 + return a ]], 5/2) test("//=", [[ -local a = 5 -a //= 2 -return a + local a = 5 + a //= 2 + return a ]], 2) test("^=", [[ -local a = 5 -a ^= 2 -return a + local a = 5 + a ^= 2 + return a ]], 25) test("%=", [[ -local a = 5 -a %= 2 -return a + local a = 5 + a %= 2 + return a ]], 5%2) test("..=", [[ -local a = "hello" -a ..= " world" -return a + local a = "hello" + a ..= " world" + return a ]], "hello world") test("and=", [[ -local a = true -a and= "world" -return a + local a = true + a and= "world" + return a ]], "world") test("or=", [[ -local a = false -a or= "world" -return a + local a = false + a or= "world" + return a ]], "world") test("&=", [[ -local a = 5 -a &= 3 -return a + local a = 5 + a &= 3 + return a ]], 1) test("|=", [[ -local a = 5 -a |= 3 -return a + local a = 5 + a |= 3 + return a ]], 7) test("<<=", [[ -local a = 23 -a <<= 2 -return a + local a = 23 + a <<= 2 + return a ]], 92) test(">>=", [[ -local a = 23 -a >>= 2 -return a + local a = 23 + a >>= 2 + return a ]], 5) test("right assigments operators", [[ -local a = 5 -a =+ 2 assert(a == 7, "=+") -a =- 2 assert(a == -5, "=-") -a =* -2 assert(a == 10, "=*") -a =/ 2 assert(a == 0.2, "=/") -a =// 2 assert(a == 10, "=//") -a =^ 2 assert(a == 1024, "=^") -a =% 2000 assert(a == 976, "=%") + local a = 5 + a =+ 2 assert(a == 7, "=+") + a =- 2 assert(a == -5, "=-") + a =* -2 assert(a == 10, "=*") + a =/ 2 assert(a == 0.2, "=/") + a =// 2 assert(a == 10, "=//") + a =^ 2 assert(a == 1024, "=^") + a =% 2000 assert(a == 976, "=%") -a = "world" -a =.. "hello " assert(a == "hello world", "=..") -a =and true assert(a == "hello world", "=and") + a = "world" + a =.. "hello " assert(a == "hello world", "=..") + a =and true assert(a == "hello world", "=and") -a = false -a =or nil assert(a == false, "=or") + a = false + a =or nil assert(a == false, "=or") -a = 3 -a =& 5 assert(a == 1, '=&') -a =| 20 assert(a == 21, "=|") -a =<< 1 assert(a == 2097152, "=<<") + a = 3 + a =& 5 assert(a == 1, '=&') + a =| 20 assert(a == 21, "=|") + a =<< 1 assert(a == 2097152, "=<<") -a = 2 -a =>> 23 assert(a == 5, "=>>") + a = 2 + a =>> 23 assert(a == 5, "=>>") ]], nil) test("some left+right assigments operators", [[ -local a = 5 -a -=+ 2 assert(a == 8, "-=+") + local a = 5 + a -=+ 2 assert(a == 8, "-=+") -a = "hello" -a ..=.. " world " assert(a == "hello world hello", "..=..") + a = "hello" + a ..=.. " world " assert(a == "hello world hello", "..=..") ]], nil) test("left assigments operators priority", [[ -local a = 5 -a *= 2 + 3 -return a + local a = 5 + a *= 2 + 3 + return a ]], 25) test("right assigments operators priority", [[ -local a = 5 -a =/ 2 + 3 -return a + local a = 5 + a =/ 2 + 3 + return a ]], 1) test("left+right assigments operators priority", [[ -local a = 5 -a *=/ 2 + 3 -return a + local a = 5 + a *=/ 2 + 3 + return a ]], 5) -- Default function parameters test("default parameters", [[ -local function test(hey, def="re", no, foo=("bar"):gsub("bar", "batru")) - return def..foo -end -return test(78, "SANDWICH", true) + local function test(hey, def="re", no, foo=("bar"):gsub("bar", "batru")) + return def..foo + end + return test(78, "SANDWICH", true) ]], "SANDWICHbatru") -- @ self alias test("@ as self alias", [[ -local a = {} -function a:hey() - return @ == self -end -return a:hey() + local a = {} + function a:hey() + return @ == self + end + return a:hey() ]], true) test("@ as self alias and indexation", [[ -local a = { - foo = "Hoi" -} -function a:hey() - return @.foo -end -return a:hey() + local a = { + foo = "Hoi" + } + function a:hey() + return @.foo + end + return a:hey() ]], "Hoi") test("@name indexation", [[ -local a = { - foo = "Hoi" -} -function a:hey() - return @foo -end -return a:hey() + local a = { + foo = "Hoi" + } + function a:hey() + return @foo + end + return a:hey() ]], "Hoi") test("@name method call", [[ -local a = { - foo = "Hoi", - bar = function(self) - return self.foo + local a = { + foo = "Hoi", + bar = function(self) + return self.foo + end + } + function a:hey() + return @bar() end -} -function a:hey() - return @bar() -end -return a:hey() + return a:hey() ]], "Hoi") test("@[expt] indexation", [[ -local a = { - foo = "Hoi" -} -function a:hey() - return @["foo"] -end -return a:hey() + local a = { + foo = "Hoi" + } + function a:hey() + return @["foo"] + end + return a:hey() ]], "Hoi") -- Short anonymous functions declaration test("short anonymous function declaration", [[ -local a = (arg1) - return arg1 -end -return a(5) + local a = (arg1) + return arg1 + end + return a(5) ]], 5) test("short anonymous method declaration", [[ -local a = :(arg1) - return self + arg1 -end -return a(2, 3) + local a = :(arg1) + return self + arg1 + end + return a(2, 3) ]], 5) test("short anonymous method parsing edge cases", [[ --- Taken from the file I used when solving this horror, too tired to make separate tests. -x = "" -function a(s) - x = x .. tostring(s or "+") -end -k=true -while k do - k=false - cap = {[0] = op, a} - a(tostring(h)) - if true then - a() - if false then - a = x, (a) - c() + -- Taken from the file I used when solving this horror, too tired to make separate tests. + x = "" + function a(s) + x = x .. tostring(s or "+") + end + k=true + while k do + k=false + cap = {[0] = op, a} + a(tostring(h)) + if true then + a() + if false then + a = x, (a) + c() + end + a() end a() end a() -end -a() -a("l") -let h = (h) - a("h") -end -h() -a("lol") -if false then exit() end -a("pmo") -if true then - if false - a = (h) + a("l") + let h = (h) + a("h") + end + h() + a("lol") + if false then exit() end + a("pmo") + if true then + if false + a = (h) - a() - a("pom") -end -a("lo") -a("kol") -if false then - j() - p() -end -do - b = [ - k = () end - if false - k = (lol) - error("niet") - end + a() + a("pom") + end + a("lo") + a("kol") + if false then + j() + p() + end + do + b = [ + k = () end + if false + k = (lol) + error("niet") + end - k() - a()] -end -if a() then h() end -local function f (...) - if select('#', ...) == 1 then - return (...) - else - return "***" - end -end -return f(x) + k() + a()] + end + if a() then h() end + local function f (...) + if select('#', ...) == 1 then + return (...) + else + return "***" + end + end + return f(x) ]], "nil++++lhlolpmo+pomlokol++") -- let variable declaration test("let variable declaration", [[ -let a = { - foo = function() - return type(a) - end -} -return a.foo() + let a = { + foo = function() + return type(a) + end + } + return a.foo() ]], "table") -- continue keyword test("continue keyword in while", [[ -local a = "" -local i = 0 -while i < 10 do - i = i + 1 - if i % 2 == 0 then - continue + local a = "" + local i = 0 + while i < 10 do + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i end - a = a .. i -end -return a + return a ]], "13579") test("continue keyword in while, used with break", [[ -local a = "" -local i = 0 -while i < 10 do - i = i + 1 - if i % 2 == 0 then - continue + local a = "" + local i = 0 + while i < 10 do + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end end - a = a .. i - if i == 5 then - break - end -end -return a + return a ]], "135") test("continue keyword in repeat", [[ -local a = "" -local i = 0 -repeat - i = i + 1 - if i % 2 == 0 then - continue - end - a = a .. i -until i == 10 -return a + local a = "" + local i = 0 + repeat + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i + until i == 10 + return a ]], "13579") test("continue keyword in repeat, used with break", [[ -local a = "" -local i = 0 -repeat - i = i + 1 - if i % 2 == 0 then - continue - end - a = a .. i - if i == 5 then - break - end -until i == 10 -return a + local a = "" + local i = 0 + repeat + i = i + 1 + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end + until i == 10 + return a ]], "135") test("continue keyword in fornum", [[ -local a = "" -for i=1, 10 do - if i % 2 == 0 then - continue + local a = "" + for i=1, 10 do + if i % 2 == 0 then + continue + end + a = a .. i end - a = a .. i -end -return a + return a ]], "13579") test("continue keyword in fornum, used with break", [[ -local a = "" -for i=1, 10 do - if i % 2 == 0 then - continue + local a = "" + for i=1, 10 do + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end end - a = a .. i - if i == 5 then - break - end -end -return a + return a ]], "135") test("continue keyword in for", [[ -local t = {1,2,3,4,5,6,7,8,9,10} -local a = "" -for _, i in ipairs(t) do - if i % 2 == 0 then - continue + local t = {1,2,3,4,5,6,7,8,9,10} + local a = "" + for _, i in ipairs(t) do + if i % 2 == 0 then + continue + end + a = a .. i end - a = a .. i -end -return a + return a ]], "13579") test("continue keyword in for, used with break", [[ -local t = {1,2,3,4,5,6,7,8,9,10} -local a = "" -for _, i in ipairs(t) do - if i % 2 == 0 then - continue + local t = {1,2,3,4,5,6,7,8,9,10} + local a = "" + for _, i in ipairs(t) do + if i % 2 == 0 then + continue + end + a = a .. i + if i == 5 then + break + end end - a = a .. i - if i == 5 then - break - end -end -return a + return a ]], "135") -- push keyword test("push keyword", [[ -function a() - for i=1, 5 do - push i, "next" + function a() + for i=1, 5 do + push i, "next" + end + return "done" end - return "done" -end -return table.concat({a()}) + return table.concat({a()}) ]], "1next2next3next4next5nextdone") test("push keyword variable length", [[ -function v() - return "hey", "hop" -end -function w() - return "foo", "bar" -end -function a() - push 5, v(), w() - return -end -return table.concat({a()}) + function v() + return "hey", "hop" + end + function w() + return "foo", "bar" + end + function a() + push 5, v(), w() + return + end + return table.concat({a()}) ]], "5heyfoobar") -- implicit push test("implicit push", [[ -function a() - for i=1, 5 do - i, "next" + function a() + for i=1, 5 do + i, "next" + end + return "done" end - return "done" -end -return table.concat({a()}) + return table.concat({a()}) ]], "1next2next3next4next5nextdone") test("implicit push variable length", [[ -function v() - return "hey", "hop" -end -function w() - return "foo", "bar" -end -function a() - if true then - 5, v(), w() + function v() + return "hey", "hop" end -end -return table.concat({a()}) + function w() + return "foo", "bar" + end + function a() + if true then + 5, v(), w() + end + end + return table.concat({a()}) ]], "5heyfoobar") -- statement expressions test("if statement expressions", [[ -a = if false then - "foo" -- i.e. push "foo", i.e. return "foo" -else - "bar" -end -return a + a = if false then + "foo" -- i.e. push "foo", i.e. return "foo" + else + "bar" + end + return a ]], "bar") test("do statement expressions", [[ -a = do - "bar" -end -return a + a = do + "bar" + end + return a ]], "bar") test("while statement expressions", [[ -i=0 -a, b, c = while i<2 do i=i+1; i end -return table.concat({a, b, tostring(c)}) + i=0 + a, b, c = while i<2 do i=i+1; i end + return table.concat({a, b, tostring(c)}) ]], "12nil") test("repeat statement expressions", [[ -local i = 0 -a, b, c = repeat i=i+1; i until i==2 -return table.concat({a, b, tostring(c)}) + local i = 0 + a, b, c = repeat i=i+1; i until i==2 + return table.concat({a, b, tostring(c)}) ]], "12nil") test("for statement expressions", [[ -a, b, c = for i=1,2 do i end -return table.concat({a, b, tostring(c)}) + a, b, c = for i=1,2 do i end + return table.concat({a, b, tostring(c)}) ]], "12nil") -- table comprehension test("table comprehension sequence", [[ -return table.concat([for i=1,10 do i end]) + return table.concat([for i=1,10 do i end]) ]], "12345678910") test("table comprehension associative/self", [[ -a = [for i=1, 10 do @[i] = true end] -return a[1] and a[10] + a = [for i=1, 10 do @[i] = true end] + return a[1] and a[10] ]], true) test("table comprehension variable length", [[ -t1 = {"hey", "hop"} -t2 = {"foo", "bar"} -return table.concat([push unpack(t1); push unpack(t2)]) + t1 = {"hey", "hop"} + t2 = {"foo", "bar"} + return table.concat([push unpack(t1); push unpack(t2)]) ]], "heyhopfoobar") -- one line statements test("one line if", [[ -a = 5 -if false - a = 0 -return a + a = 5 + if false + a = 0 + return a ]], 5) test("one line if-elseif", [[ -a = 5 -if false - a = 0 -elseif true - a = 3 -elseif false - a = -1 -return a + a = 5 + if false + a = 0 + elseif true + a = 3 + elseif false + a = -1 + return a ]], 3) test("one line for", [[ -a = 0 -for i=1,5 - a = a + 1 -return a + a = 0 + for i=1,5 + a = a + 1 + return a ]], 5) test("one line while", [[ -a = 0 -while a < 5 - a = a + 1 -return a + a = 0 + while a < 5 + a = a + 1 + return a ]], 5) -- suffixable string litals, table, table comprehension test("suffixable string litteral method", [[ -return "foo":len() + return "foo":len() ]], 3) test("suffixable string litteral method lua conflict", [[ -local s = function() return "four" end -return s"foo":len() + local s = function() return "four" end + return s"foo":len() ]], 4) test("suffixable string litteral dot index", [[ -local a = "foo".len -return a("foo") + local a = "foo".len + return a("foo") ]], 3) test("suffixable string litteral dot index lua conflict", [[ -local s = function() return {len=4} end -local a = s"foo".len -return a + local s = function() return {len=4} end + local a = s"foo".len + return a ]], 4) test("suffixable string litteral array index", [[ -local a = "foo"["len"] -return a("foo") + local a = "foo"["len"] + return a("foo") ]], 3) test("suffixable string litteral dot index lua conflict", [[ -local s = function() return {len=4} end -local a = s"foo"["len"] -return a + local s = function() return {len=4} end + local a = s"foo"["len"] + return a ]], 4) test("suffixable table litteral method", [[ -return {a=3,len=function(t) return t.a end}:len() + return {a=3,len=function(t) return t.a end}:len() ]], 3) test("suffixable table litteral method lua conflict", [[ -local s = function() return "four" end -return s{a=3,len=function(t) return t.a end}:len() + local s = function() return "four" end + return s{a=3,len=function(t) return t.a end}:len() ]], 4) test("suffixable table litteral dot index", [[ -return {len=3}.len + return {len=3}.len ]], 3) test("suffixable table litteral dot index lua conflict", [[ -local s = function() return {len=4} end -return s{len=3}.len + local s = function() return {len=4} end + return s{len=3}.len ]], 4) test("suffixable table litteral array index", [[ -return {len=3}["len"] + return {len=3}["len"] ]], 3) test("suffixable table litteral dot index lua conflict", [[ -local s = function() return {len=4} end -return s{len=3}["len"] + local s = function() return {len=4} end + return s{len=3}["len"] ]], 4) test("suffixable table comprehension method", [[ -return [@len = function() return 3 end]:len() + return [@len = function() return 3 end]:len() ]], 3) test("suffixable table comprehension dot index", [[ -return [@len = 3].len + return [@len = 3].len ]], 3) test("suffixable table comprehension array index", [[ -return [@len=3]["len"] + return [@len=3]["len"] ]], 3) -- let in condition expression @@ -823,6 +827,187 @@ test("safe prefixes, random chaining", [[ assert(f.l?:o?() == nil) ]]) +-- Destructuring assigments +test("destructuring assignement with an expression", [[ + local {x, y} = { x = 5, y = 1 } + return x + y +]], 6) +test("destructuring assignement with local", [[ + t = { x = 5, y = 1 } + local {x, y} = t + return x + y +]], 6) +test("destructuring assignement", [[ + t = { x = 5, y = 1 } + {x, y} = t + return x + y +]], 6) +test("destructuring assignement with +=", [[ + t = { x = 5, y = 1 } + local x, y = 5, 9 + {x, y} += t + return x + y +]], 20) +test("destructuring assignement with =-", [[ + t = { x = 5, y = 1 } + local x, y = 5, 9 + {x, y} =- t + return x + y +]], -8) +test("destructuring assignement with +=-", [[ + t = { x = 5, y = 1 } + local x, y = 5, 9 + {x, y} +=- t + return x + y +]], 6) +test("destructuring assignement with =-", [[ + t = { x = 5, y = 1 } + local x, y = 5, 9 + {x, y} =- t + return x + y +]], -8) +test("destructuring assignement with let", [[ + t = { x = 5, y = 1 } + let {x, y} = t + return x + y +]], 6) +test("destructuring assignement with for in", [[ + t = {{ x = 5, y = 1 }} + for k, {x, y} in pairs(t) do + return x + y + end +]], 6) +test("destructuring assignement with if with assignement", [[ + t = { x = 5, y = 1 } + if {x, y} = t then + return x + y + end +]], 6) +test("destructuring assignement with if-elseif with assignement", [[ + t = { x = 5, y = 1 } + if ({u} = t) and u then + return 0 + elseif {x, y} = t then + return x + y + end +]], 6) + +test("destructuring assignement with an expression with custom name", [[ + local {o = x, y} = { o = 5, y = 1 } + return x + y +]], 6) +test("destructuring assignement with local with custom name", [[ + t = { o = 5, y = 1 } + local {o = x, y} = t + return x + y +]], 6) +test("destructuring assignement with custom name", [[ + t = { o = 5, y = 1 } + {o = x, y} = t + return x + y +]], 6) +test("destructuring assignement with += with custom name", [[ + t = { o = 5, y = 1 } + local x, y = 5, 9 + {o = x, y} += t + return x + y +]], 20) +test("destructuring assignement with =- with custom name", [[ + t = { o = 5, y = 1 } + local x, y = 5, 9 + {o = x, y} =- t + return x + y +]], -8) +test("destructuring assignement with +=- with custom name", [[ + t = { o = 5, y = 1 } + local x, y = 5, 9 + {o = x, y} +=- t + return x + y +]], 6) +test("destructuring assignement with let with custom name", [[ + t = { o = 5, y = 1 } + let {o = x, y} = t + return x + y +]], 6) +test("destructuring assignement with for in with custom name", [[ + t = {{ o = 5, y = 1 }} + for k, {o = x, y} in pairs(t) do + return x + y + end +]], 6) +test("destructuring assignement with if with assignement with custom name", [[ + t = { o = 5, y = 1 } + if {o = x, y} = t then + return x + y + end +]], 6) +test("destructuring assignement with if-elseif with assignement with custom name", [[ + t = { o = 5, y = 1 } + if ({x} = t) and x then + return 0 + elseif {o = x, y} = t then + return x + y + end +]], 6) + +test("destructuring assignement with an expression with expression as key", [[ + local {[1] = x, y} = { 5, y = 1 } + return x + y +]], 6) +test("destructuring assignement with local with expression as key", [[ + t = { 5, y = 1 } + local {[1] = x, y} = t + return x + y +]], 6) +test("destructuring assignement with expression as key", [[ + t = { 5, y = 1 } + {[1] = x, y} = t + return x + y +]], 6) +test("destructuring assignement with += with expression as key", [[ + t = { 5, y = 1 } + local x, y = 5, 9 + {[1] = x, y} += t + return x + y +]], 20) +test("destructuring assignement with =- with expression as key", [[ + t = { 5, y = 1 } + local x, y = 5, 9 + {[1] = x, y} =- t + return x + y +]], -8) +test("destructuring assignement with +=- with expression as key", [[ + t = { 5, y = 1 } + local x, y = 5, 9 + {[1] = x, y} +=- t + return x + y +]], 6) +test("destructuring assignement with let with expression as key", [[ + t = { 5, y = 1 } + let {[1] = x, y} = t + return x + y +]], 6) +test("destructuring assignement with for in with expression as key", [[ + t = {{ 5, y = 1 }} + for k, {[1] = x, y} in pairs(t) do + return x + y + end +]], 6) +test("destructuring assignement with if with assignement with expression as key", [[ + t = { 5, y = 1 } + if {[1] = x, y} = t then + return x + y + end +]], 6) +test("destructuring assignement with if-elseif with assignement with expression as key", [[ + t = { 5, y = 1 } + if ({x} = t) and x then + return 0 + elseif {[1] = x, y} = t then + return x + y + end +]], 6) + -- results local resultCounter = {} local testCounter = 0 From 5fff7612f42a96e4a4d6fb3e1df585b0c3849aa3 Mon Sep 17 00:00:00 2001 From: Reuh Date: Wed, 15 Jan 2020 20:59:59 +0100 Subject: [PATCH 08/52] Candran 0.11.0 --- rockspec/candran-0.11.0-1.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rockspec/candran-0.11.0-1.rockspec b/rockspec/candran-0.11.0-1.rockspec index 674956a..fb04283 100644 --- a/rockspec/candran-0.11.0-1.rockspec +++ b/rockspec/candran-0.11.0-1.rockspec @@ -2,7 +2,7 @@ rockspec_format = "3.0" package = "candran" -version = "0.10.0-1" +version = "0.11.0-1" description = { summary = "A simple Lua dialect and preprocessor.", From dc19ac56a9c3779b39f2d6a3d61adefdc5c08835 Mon Sep 17 00:00:00 2001 From: Reuh Date: Sun, 19 Jan 2020 15:36:25 +0100 Subject: [PATCH 09/52] Rename lib to candran --- bin/can | 2 +- bin/canc | 6 +- candran.can | 12 +- candran.lua | 3973 +++++++++-------- .../lua-parser => candran/can-parser}/LICENSE | 0 .../can-parser}/README.md | 0 .../can-parser}/parser.lua | 10 +- {lib/lua-parser => candran/can-parser}/pp.lua | 0 .../can-parser}/scope.lua | 0 .../can-parser}/validator.lua | 2 +- {lib => candran}/cmdline.lua | 0 {lib => candran}/util.can | 0 test/test.lua | 2 +- 13 files changed, 2007 insertions(+), 2000 deletions(-) rename {lib/lua-parser => candran/can-parser}/LICENSE (100%) rename {lib/lua-parser => candran/can-parser}/README.md (100%) rename {lib/lua-parser => candran/can-parser}/parser.lua (98%) rename {lib/lua-parser => candran/can-parser}/pp.lua (100%) rename {lib/lua-parser => candran/can-parser}/scope.lua (100%) rename {lib/lua-parser => candran/can-parser}/validator.lua (99%) rename {lib => candran}/cmdline.lua (100%) rename {lib => candran}/util.can (100%) diff --git a/bin/can b/bin/can index c2987b4..2ec98fd 100644 --- a/bin/can +++ b/bin/can @@ -1,6 +1,6 @@ #!/bin/lua local candran = require("candran") -local cmdline = require("lib.cmdline") +local cmdline = require("candran.cmdline") local args = cmdline(arg) diff --git a/bin/canc b/bin/canc index cd0b7ef..d6fbb6c 100644 --- a/bin/canc +++ b/bin/canc @@ -1,8 +1,8 @@ #!/bin/lua local candran = require("candran") -local cmdline = require("lib.cmdline") -local parse = require("lib.lua-parser.parser").parse -local pp = require("lib.lua-parser.pp") +local cmdline = require("candran.cmdline") +local parse = require("candran.can-parser.parser").parse +local pp = require("candran.can-parser.pp") local args = cmdline(arg) diff --git a/candran.can b/candran.can index 049d4ef..3bbed3b 100644 --- a/candran.can +++ b/candran.can @@ -1,14 +1,14 @@ -#import("lib.util") -#import("lib.cmdline") +#import("candran.util") +#import("candran.cmdline") #import("compiler.lua53") #import("compiler.luajit") #import("compiler.lua51") -#import("lib.lua-parser.scope") -#import("lib.lua-parser.validator") -#import("lib.lua-parser.pp") -#import("lib.lua-parser.parser") +#import("candran.can-parser.scope") +#import("candran.can-parser.validator") +#import("candran.can-parser.pp") +#import("candran.can-parser.parser") local candran = { VERSION = "0.11.0" diff --git a/candran.lua b/candran.lua index e6aae42..bc6f34a 100644 --- a/candran.lua +++ b/candran.lua @@ -1,140 +1,140 @@ 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 = {} 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 -local f = io["open"](fpath) -- ./lib/util.can:7 -if f then -- ./lib/util.can:8 -f:close() -- ./lib/util.can:9 -return fpath -- ./lib/util.can:10 -end -- ./lib/util.can:10 -end -- ./lib/util.can:10 -end -- ./lib/util.can:10 -end -- ./lib/util.can:10 -util["load"] = function(str, name, env) -- ./lib/util.can:16 -if _VERSION == "Lua 5.1" then -- ./lib/util.can:17 -local fn, err = loadstring(str, name) -- ./lib/util.can:18 -if not fn then -- ./lib/util.can:19 -return fn, err -- ./lib/util.can:19 -end -- ./lib/util.can:19 -return env ~= nil and setfenv(fn, env) or fn -- ./lib/util.can:20 -else -- ./lib/util.can:20 -if env then -- ./lib/util.can:22 -return load(str, name, nil, env) -- ./lib/util.can:23 -else -- ./lib/util.can:23 -return load(str, name) -- ./lib/util.can:25 -end -- ./lib/util.can:25 -end -- ./lib/util.can:25 -end -- ./lib/util.can:25 -util["merge"] = function(...) -- ./lib/util.can:30 -local r = {} -- ./lib/util.can:31 -for _, t in ipairs({ ... }) do -- ./lib/util.can:32 -for k, v in pairs(t) do -- ./lib/util.can:33 -r[k] = v -- ./lib/util.can:34 -end -- ./lib/util.can:34 -end -- ./lib/util.can:34 -return r -- ./lib/util.can:37 -end -- ./lib/util.can:37 -return util -- ./lib/util.can:40 -end -- ./lib/util.can:40 -local util = _() or util -- ./lib/util.can:44 -package["loaded"]["lib.util"] = util or true -- ./lib/util.can:45 -local function _() -- ./lib/util.can:48 -local ipairs, pairs, setfenv, tonumber, loadstring, type = ipairs, pairs, setfenv, tonumber, loadstring, type -- ./lib/cmdline.lua:5 -local tinsert, tconcat = table["insert"], table["concat"] -- ./lib/cmdline.lua:6 -local function commonerror(msg) -- ./lib/cmdline.lua:8 -return nil, ("[cmdline]: " .. msg) -- ./lib/cmdline.lua:9 -end -- ./lib/cmdline.lua:9 -local function argerror(msg, numarg) -- ./lib/cmdline.lua:12 -msg = msg and (": " .. msg) or "" -- ./lib/cmdline.lua:13 -return nil, ("[cmdline]: bad argument #" .. numarg .. msg) -- ./lib/cmdline.lua:14 -end -- ./lib/cmdline.lua:14 -local function iderror(numarg) -- ./lib/cmdline.lua:17 -return argerror("ID not valid", numarg) -- ./lib/cmdline.lua:18 -end -- ./lib/cmdline.lua:18 -local function idcheck(id) -- ./lib/cmdline.lua:21 -return id:match("^[%a_][%w_]*$") and true -- ./lib/cmdline.lua:22 -end -- ./lib/cmdline.lua:22 -return function(t_in, options, params) -- ./lib/cmdline.lua:73 -local t_out = {} -- ./lib/cmdline.lua:74 -for i, v in ipairs(t_in) do -- ./lib/cmdline.lua:75 -local prefix, command = v:sub(1, 1), v:sub(2) -- ./lib/cmdline.lua:76 -if prefix == "$" then -- ./lib/cmdline.lua:77 -tinsert(t_out, command) -- ./lib/cmdline.lua:78 -elseif prefix == "-" then -- ./lib/cmdline.lua:79 -for id in command:gmatch("[^,;]+") do -- ./lib/cmdline.lua:80 -if not idcheck(id) then -- ./lib/cmdline.lua:81 -return iderror(i) -- ./lib/cmdline.lua:81 -end -- ./lib/cmdline.lua:81 -t_out[id] = true -- ./lib/cmdline.lua:82 -end -- ./lib/cmdline.lua:82 -elseif prefix == "!" then -- ./lib/cmdline.lua:84 -local f, err = loadstring(command) -- ./lib/cmdline.lua:85 -if not f then -- ./lib/cmdline.lua:86 -return argerror(err, i) -- ./lib/cmdline.lua:86 -end -- ./lib/cmdline.lua:86 -setfenv(f, t_out)() -- ./lib/cmdline.lua:87 -elseif v:find("=") then -- ./lib/cmdline.lua:88 -local ids, val = v:match("^([^=]+)%=(.*)") -- no space around = -- ./lib/cmdline.lua:89 -if not ids then -- ./lib/cmdline.lua:90 -return argerror("invalid assignment syntax", i) -- ./lib/cmdline.lua:90 -end -- ./lib/cmdline.lua:90 -if val == "false" then -- ./lib/cmdline.lua:91 -val = false -- ./lib/cmdline.lua:92 -elseif val == "true" then -- ./lib/cmdline.lua:93 -val = true -- ./lib/cmdline.lua:94 -else -- ./lib/cmdline.lua:94 -val = val:sub(1, 1) == "$" and val:sub(2) or tonumber(val) or val -- ./lib/cmdline.lua:96 -end -- ./lib/cmdline.lua:96 -for id in ids:gmatch("[^,;]+") do -- ./lib/cmdline.lua:98 -if not idcheck(id) then -- ./lib/cmdline.lua:99 -return iderror(i) -- ./lib/cmdline.lua:99 -end -- ./lib/cmdline.lua:99 -t_out[id] = val -- ./lib/cmdline.lua:100 -end -- ./lib/cmdline.lua:100 -else -- ./lib/cmdline.lua:100 -tinsert(t_out, v) -- ./lib/cmdline.lua:103 -end -- ./lib/cmdline.lua:103 -end -- ./lib/cmdline.lua:103 -if options then -- ./lib/cmdline.lua:106 -local lookup, unknown = {}, {} -- ./lib/cmdline.lua:107 -for _, v in ipairs(options) do -- ./lib/cmdline.lua:108 -lookup[v] = true -- ./lib/cmdline.lua:108 -end -- ./lib/cmdline.lua:108 -for k, _ in pairs(t_out) do -- ./lib/cmdline.lua:109 -if lookup[k] == nil and type(k) == "string" then -- ./lib/cmdline.lua:110 -tinsert(unknown, k) -- ./lib/cmdline.lua:110 -end -- ./lib/cmdline.lua:110 -end -- ./lib/cmdline.lua:110 -if # unknown > 0 then -- ./lib/cmdline.lua:112 -return commonerror("unknown options: " .. tconcat(unknown, ", ")) -- ./lib/cmdline.lua:113 -end -- ./lib/cmdline.lua:113 -end -- ./lib/cmdline.lua:113 -if params then -- ./lib/cmdline.lua:116 -local missing = {} -- ./lib/cmdline.lua:117 -for _, v in ipairs(params) do -- ./lib/cmdline.lua:118 -if t_out[v] == nil then -- ./lib/cmdline.lua:119 -tinsert(missing, v) -- ./lib/cmdline.lua:119 -end -- ./lib/cmdline.lua:119 -end -- ./lib/cmdline.lua:119 -if # missing > 0 then -- ./lib/cmdline.lua:121 -return commonerror("missing parameters: " .. tconcat(missing, ", ")) -- ./lib/cmdline.lua:122 -end -- ./lib/cmdline.lua:122 -end -- ./lib/cmdline.lua:122 -return t_out -- ./lib/cmdline.lua:125 -end -- ./lib/cmdline.lua:125 -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 +local util = {} -- ./candran/util.can:1 +util["search"] = function(modpath, exts) -- ./candran/util.can:3 +if exts == nil then exts = {} end -- ./candran/util.can:3 +for _, ext in ipairs(exts) do -- ./candran/util.can:4 +for path in package["path"]:gmatch("[^;]+") do -- ./candran/util.can:5 +local fpath = path:gsub("%.lua", "." .. ext):gsub("%?", (modpath:gsub("%.", "/"))) -- ./candran/util.can:6 +local f = io["open"](fpath) -- ./candran/util.can:7 +if f then -- ./candran/util.can:8 +f:close() -- ./candran/util.can:9 +return fpath -- ./candran/util.can:10 +end -- ./candran/util.can:10 +end -- ./candran/util.can:10 +end -- ./candran/util.can:10 +end -- ./candran/util.can:10 +util["load"] = function(str, name, env) -- ./candran/util.can:16 +if _VERSION == "Lua 5.1" then -- ./candran/util.can:17 +local fn, err = loadstring(str, name) -- ./candran/util.can:18 +if not fn then -- ./candran/util.can:19 +return fn, err -- ./candran/util.can:19 +end -- ./candran/util.can:19 +return env ~= nil and setfenv(fn, env) or fn -- ./candran/util.can:20 +else -- ./candran/util.can:20 +if env then -- ./candran/util.can:22 +return load(str, name, nil, env) -- ./candran/util.can:23 +else -- ./candran/util.can:23 +return load(str, name) -- ./candran/util.can:25 +end -- ./candran/util.can:25 +end -- ./candran/util.can:25 +end -- ./candran/util.can:25 +util["merge"] = function(...) -- ./candran/util.can:30 +local r = {} -- ./candran/util.can:31 +for _, t in ipairs({ ... }) do -- ./candran/util.can:32 +for k, v in pairs(t) do -- ./candran/util.can:33 +r[k] = v -- ./candran/util.can:34 +end -- ./candran/util.can:34 +end -- ./candran/util.can:34 +return r -- ./candran/util.can:37 +end -- ./candran/util.can:37 +return util -- ./candran/util.can:40 +end -- ./candran/util.can:40 +local util = _() or util -- ./candran/util.can:44 +package["loaded"]["candran.util"] = util or true -- ./candran/util.can:45 +local function _() -- ./candran/util.can:48 +local ipairs, pairs, setfenv, tonumber, loadstring, type = ipairs, pairs, setfenv, tonumber, loadstring, type -- ./candran/cmdline.lua:5 +local tinsert, tconcat = table["insert"], table["concat"] -- ./candran/cmdline.lua:6 +local function commonerror(msg) -- ./candran/cmdline.lua:8 +return nil, ("[cmdline]: " .. msg) -- ./candran/cmdline.lua:9 +end -- ./candran/cmdline.lua:9 +local function argerror(msg, numarg) -- ./candran/cmdline.lua:12 +msg = msg and (": " .. msg) or "" -- ./candran/cmdline.lua:13 +return nil, ("[cmdline]: bad argument #" .. numarg .. msg) -- ./candran/cmdline.lua:14 +end -- ./candran/cmdline.lua:14 +local function iderror(numarg) -- ./candran/cmdline.lua:17 +return argerror("ID not valid", numarg) -- ./candran/cmdline.lua:18 +end -- ./candran/cmdline.lua:18 +local function idcheck(id) -- ./candran/cmdline.lua:21 +return id:match("^[%a_][%w_]*$") and true -- ./candran/cmdline.lua:22 +end -- ./candran/cmdline.lua:22 +return function(t_in, options, params) -- ./candran/cmdline.lua:73 +local t_out = {} -- ./candran/cmdline.lua:74 +for i, v in ipairs(t_in) do -- ./candran/cmdline.lua:75 +local prefix, command = v:sub(1, 1), v:sub(2) -- ./candran/cmdline.lua:76 +if prefix == "$" then -- ./candran/cmdline.lua:77 +tinsert(t_out, command) -- ./candran/cmdline.lua:78 +elseif prefix == "-" then -- ./candran/cmdline.lua:79 +for id in command:gmatch("[^,;]+") do -- ./candran/cmdline.lua:80 +if not idcheck(id) then -- ./candran/cmdline.lua:81 +return iderror(i) -- ./candran/cmdline.lua:81 +end -- ./candran/cmdline.lua:81 +t_out[id] = true -- ./candran/cmdline.lua:82 +end -- ./candran/cmdline.lua:82 +elseif prefix == "!" then -- ./candran/cmdline.lua:84 +local f, err = loadstring(command) -- ./candran/cmdline.lua:85 +if not f then -- ./candran/cmdline.lua:86 +return argerror(err, i) -- ./candran/cmdline.lua:86 +end -- ./candran/cmdline.lua:86 +setfenv(f, t_out)() -- ./candran/cmdline.lua:87 +elseif v:find("=") then -- ./candran/cmdline.lua:88 +local ids, val = v:match("^([^=]+)%=(.*)") -- ./candran/cmdline.lua:89 +if not ids then -- ./candran/cmdline.lua:90 +return argerror("invalid assignment syntax", i) -- ./candran/cmdline.lua:90 +end -- ./candran/cmdline.lua:90 +if val == "false" then -- ./candran/cmdline.lua:91 +val = false -- ./candran/cmdline.lua:92 +elseif val == "true" then -- ./candran/cmdline.lua:93 +val = true -- ./candran/cmdline.lua:94 +else -- ./candran/cmdline.lua:94 +val = val:sub(1, 1) == "$" and val:sub(2) or tonumber(val) or val -- ./candran/cmdline.lua:96 +end -- ./candran/cmdline.lua:96 +for id in ids:gmatch("[^,;]+") do -- ./candran/cmdline.lua:98 +if not idcheck(id) then -- ./candran/cmdline.lua:99 +return iderror(i) -- ./candran/cmdline.lua:99 +end -- ./candran/cmdline.lua:99 +t_out[id] = val -- ./candran/cmdline.lua:100 +end -- ./candran/cmdline.lua:100 +else -- ./candran/cmdline.lua:100 +tinsert(t_out, v) -- ./candran/cmdline.lua:103 +end -- ./candran/cmdline.lua:103 +end -- ./candran/cmdline.lua:103 +if options then -- ./candran/cmdline.lua:106 +local lookup, unknown = {}, {} -- ./candran/cmdline.lua:107 +for _, v in ipairs(options) do -- ./candran/cmdline.lua:108 +lookup[v] = true -- ./candran/cmdline.lua:108 +end -- ./candran/cmdline.lua:108 +for k, _ in pairs(t_out) do -- ./candran/cmdline.lua:109 +if lookup[k] == nil and type(k) == "string" then -- ./candran/cmdline.lua:110 +tinsert(unknown, k) -- ./candran/cmdline.lua:110 +end -- ./candran/cmdline.lua:110 +end -- ./candran/cmdline.lua:110 +if # unknown > 0 then -- ./candran/cmdline.lua:112 +return commonerror("unknown options: " .. tconcat(unknown, ", ")) -- ./candran/cmdline.lua:113 +end -- ./candran/cmdline.lua:113 +end -- ./candran/cmdline.lua:113 +if params then -- ./candran/cmdline.lua:116 +local missing = {} -- ./candran/cmdline.lua:117 +for _, v in ipairs(params) do -- ./candran/cmdline.lua:118 +if t_out[v] == nil then -- ./candran/cmdline.lua:119 +tinsert(missing, v) -- ./candran/cmdline.lua:119 +end -- ./candran/cmdline.lua:119 +end -- ./candran/cmdline.lua:119 +if # missing > 0 then -- ./candran/cmdline.lua:121 +return commonerror("missing parameters: " .. tconcat(missing, ", ")) -- ./candran/cmdline.lua:122 +end -- ./candran/cmdline.lua:122 +end -- ./candran/cmdline.lua:122 +return t_out -- ./candran/cmdline.lua:125 +end -- ./candran/cmdline.lua:125 +end -- ./candran/cmdline.lua:125 +local cmdline = _() or cmdline -- ./candran/cmdline.lua:130 +package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua:131 +local function _() -- ./candran/cmdline.lua:135 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 lastInputPos = 1 -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 +local lastLine = 1 -- ./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 @@ -166,10 +166,10 @@ indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 return newline() -- ./compiler/lua53.can:42 end -- ./compiler/lua53.can:42 local states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 -["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 -} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +["push"] = {}, -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- ./compiler/lua53.can:49 +["scope"] = {} -- ./compiler/lua53.can:50 +} -- ./compiler/lua53.can:50 local function push(name, state) -- ./compiler/lua53.can:53 table["insert"](states[name], state) -- ./compiler/lua53.can:54 return "" -- ./compiler/lua53.can:55 @@ -194,7 +194,7 @@ local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/l table["insert"](scope, var) -- ./compiler/lua53.can:82 return var -- ./compiler/lua53.can:83 end -- ./compiler/lua53.can:83 -local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local required = {} -- ./compiler/lua53.can:87 local requireStr = "" -- ./compiler/lua53.can:88 local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 @@ -203,26 +203,26 @@ requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options[" required[req] = true -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 -local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local loop = { -- ./compiler/lua53.can:99 +"While", -- ./compiler/lua53.can:99 +"Repeat", -- ./compiler/lua53.can:99 +"Fornum", -- ./compiler/lua53.can:99 +"Forin", -- ./compiler/lua53.can:99 +"WhileExpr", -- ./compiler/lua53.can:99 +"RepeatExpr", -- ./compiler/lua53.can:99 +"FornumExpr", -- ./compiler/lua53.can:99 +"ForinExpr" -- ./compiler/lua53.can:99 +} -- ./compiler/lua53.can:99 +local func = { -- ./compiler/lua53.can:100 +"Function", -- ./compiler/lua53.can:100 +"TableCompr", -- ./compiler/lua53.can:100 +"DoExpr", -- ./compiler/lua53.can:100 +"WhileExpr", -- ./compiler/lua53.can:100 +"RepeatExpr", -- ./compiler/lua53.can:100 +"IfExpr", -- ./compiler/lua53.can:100 +"FornumExpr", -- ./compiler/lua53.can:100 +"ForinExpr" -- ./compiler/lua53.can:100 +} -- ./compiler/lua53.can:100 local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 local tagsCheck = {} -- ./compiler/lua53.can:105 @@ -295,21 +295,21 @@ lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 end -- ./compiler/lua53.can:176 return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 local vars = {} -- ./compiler/lua53.can:195 local values = {} -- ./compiler/lua53.can:196 for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 @@ -385,8 +385,8 @@ end -- ./compiler/lua53.can:228 end -- ./compiler/lua53.can:228 tags = setmetatable({ -- ./compiler/lua53.can:233 ["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 hasPush = false -- ./compiler/lua53.can:239 end -- ./compiler/lua53.can:239 @@ -400,7 +400,7 @@ end -- ./compiler/lua53.can:246 if t[# t] then -- ./compiler/lua53.can:248 r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 end -- ./compiler/lua53.can:252 return r .. pop("scope") -- ./compiler/lua53.can:254 @@ -578,7 +578,7 @@ return r -- ./compiler/lua53.can:379 end, -- ./compiler/lua53.can:379 ["If"] = function(t) -- ./compiler/lua53.can:382 local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local toClose = 0 -- ./compiler/lua53.can:384 local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 if # lets > 0 then -- ./compiler/lua53.can:386 r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 @@ -662,13 +662,13 @@ local destructured = {} -- ./compiler/lua53.can:468 local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 local r = "local " .. nameList -- ./compiler/lua53.can:470 if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +if all(t[2], { -- ./compiler/lua53.can:472 +"Nil", -- ./compiler/lua53.can:472 +"Dots", -- ./compiler/lua53.can:472 +"Boolean", -- ./compiler/lua53.can:472 +"Number", -- ./compiler/lua53.can:472 +"String" -- ./compiler/lua53.can:472 +}) then -- ./compiler/lua53.can:472 r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 else -- ./compiler/lua53.can:473 r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 @@ -762,17 +762,17 @@ r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 r = r .. (d .. newline()) -- ./compiler/lua53.can:581 end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 end -- ./compiler/lua53.can:584 local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 if hasPush then -- ./compiler/lua53.can:587 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 else -- ./compiler/lua53.can:588 -push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 -end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +push("push", false) -- ./compiler/lua53.can:590 +end -- ./compiler/lua53.can:590 r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 end -- ./compiler/lua53.can:594 pop("push") -- ./compiler/lua53.can:596 @@ -831,8 +831,8 @@ local r = "(function()" .. indent() -- ./compiler/lua53.can:672 if hasPush then -- ./compiler/lua53.can:673 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 else -- ./compiler/lua53.can:674 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +push("push", false) -- ./compiler/lua53.can:676 +end -- ./compiler/lua53.can:676 r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 if hasPush then -- ./compiler/lua53.can:679 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 @@ -842,7 +842,7 @@ r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 return r -- ./compiler/lua53.can:684 end, -- ./compiler/lua53.can:684 ["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 end -- ./compiler/lua53.can:689 return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 @@ -854,7 +854,7 @@ end, -- ./compiler/lua53.can:695 return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 end, -- ./compiler/lua53.can:699 ["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +for i = 2, # t do -- ./compiler/lua53.can:703 local block = t[i] -- ./compiler/lua53.can:704 if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 @@ -871,7 +871,7 @@ end, -- ./compiler/lua53.can:717 ["Call"] = function(t) -- ./compiler/lua53.can:723 if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 else -- ./compiler/lua53.can:728 @@ -882,7 +882,7 @@ return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 end -- ./compiler/lua53.can:733 end, -- ./compiler/lua53.can:733 ["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 else -- ./compiler/lua53.can:739 return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 @@ -905,7 +905,7 @@ end, -- ./compiler/lua53.can:756 return t[1] -- ./compiler/lua53.can:760 end, -- ./compiler/lua53.can:760 ["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +if t["id"] then -- ./compiler/lua53.can:764 return t["id"] -- ./compiler/lua53.can:765 else -- ./compiler/lua53.can:765 local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 @@ -926,13 +926,13 @@ return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 end -- ./compiler/lua53.can:782 end, -- ./compiler/lua53.can:782 ["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 -local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 +local l = {} -- ./compiler/lua53.can:788 while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 table["insert"](l, 1, t) -- ./compiler/lua53.can:790 t = t[1] -- ./compiler/lua53.can:791 end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 for _, e in ipairs(l) do -- ./compiler/lua53.can:794 r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 @@ -987,10 +987,10 @@ local function _() -- ./compiler/lua53.can:835 local function _() -- ./compiler/lua53.can:837 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 lastInputPos = 1 -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 +local lastLine = 1 -- ./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 @@ -1022,10 +1022,10 @@ indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 return newline() -- ./compiler/lua53.can:42 end -- ./compiler/lua53.can:42 local states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 -["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 -} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +["push"] = {}, -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- ./compiler/lua53.can:49 +["scope"] = {} -- ./compiler/lua53.can:50 +} -- ./compiler/lua53.can:50 local function push(name, state) -- ./compiler/lua53.can:53 table["insert"](states[name], state) -- ./compiler/lua53.can:54 return "" -- ./compiler/lua53.can:55 @@ -1050,7 +1050,7 @@ local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/l table["insert"](scope, var) -- ./compiler/lua53.can:82 return var -- ./compiler/lua53.can:83 end -- ./compiler/lua53.can:83 -local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local required = {} -- ./compiler/lua53.can:87 local requireStr = "" -- ./compiler/lua53.can:88 local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 @@ -1059,26 +1059,26 @@ requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options[" required[req] = true -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 -local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local loop = { -- ./compiler/lua53.can:99 +"While", -- ./compiler/lua53.can:99 +"Repeat", -- ./compiler/lua53.can:99 +"Fornum", -- ./compiler/lua53.can:99 +"Forin", -- ./compiler/lua53.can:99 +"WhileExpr", -- ./compiler/lua53.can:99 +"RepeatExpr", -- ./compiler/lua53.can:99 +"FornumExpr", -- ./compiler/lua53.can:99 +"ForinExpr" -- ./compiler/lua53.can:99 +} -- ./compiler/lua53.can:99 +local func = { -- ./compiler/lua53.can:100 +"Function", -- ./compiler/lua53.can:100 +"TableCompr", -- ./compiler/lua53.can:100 +"DoExpr", -- ./compiler/lua53.can:100 +"WhileExpr", -- ./compiler/lua53.can:100 +"RepeatExpr", -- ./compiler/lua53.can:100 +"IfExpr", -- ./compiler/lua53.can:100 +"FornumExpr", -- ./compiler/lua53.can:100 +"ForinExpr" -- ./compiler/lua53.can:100 +} -- ./compiler/lua53.can:100 local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 local tagsCheck = {} -- ./compiler/lua53.can:105 @@ -1151,21 +1151,21 @@ lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 end -- ./compiler/lua53.can:176 return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 local vars = {} -- ./compiler/lua53.can:195 local values = {} -- ./compiler/lua53.can:196 for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 @@ -1241,8 +1241,8 @@ end -- ./compiler/lua53.can:228 end -- ./compiler/lua53.can:228 tags = setmetatable({ -- ./compiler/lua53.can:233 ["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 hasPush = false -- ./compiler/lua53.can:239 end -- ./compiler/lua53.can:239 @@ -1256,7 +1256,7 @@ end -- ./compiler/lua53.can:246 if t[# t] then -- ./compiler/lua53.can:248 r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 end -- ./compiler/lua53.can:252 return r .. pop("scope") -- ./compiler/lua53.can:254 @@ -1434,7 +1434,7 @@ return r -- ./compiler/lua53.can:379 end, -- ./compiler/lua53.can:379 ["If"] = function(t) -- ./compiler/lua53.can:382 local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local toClose = 0 -- ./compiler/lua53.can:384 local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 if # lets > 0 then -- ./compiler/lua53.can:386 r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 @@ -1518,13 +1518,13 @@ local destructured = {} -- ./compiler/lua53.can:468 local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 local r = "local " .. nameList -- ./compiler/lua53.can:470 if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +if all(t[2], { -- ./compiler/lua53.can:472 +"Nil", -- ./compiler/lua53.can:472 +"Dots", -- ./compiler/lua53.can:472 +"Boolean", -- ./compiler/lua53.can:472 +"Number", -- ./compiler/lua53.can:472 +"String" -- ./compiler/lua53.can:472 +}) then -- ./compiler/lua53.can:472 r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 else -- ./compiler/lua53.can:473 r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 @@ -1618,17 +1618,17 @@ r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 r = r .. (d .. newline()) -- ./compiler/lua53.can:581 end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 end -- ./compiler/lua53.can:584 local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 if hasPush then -- ./compiler/lua53.can:587 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 else -- ./compiler/lua53.can:588 -push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 -end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +push("push", false) -- ./compiler/lua53.can:590 +end -- ./compiler/lua53.can:590 r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 end -- ./compiler/lua53.can:594 pop("push") -- ./compiler/lua53.can:596 @@ -1687,8 +1687,8 @@ local r = "(function()" .. indent() -- ./compiler/lua53.can:672 if hasPush then -- ./compiler/lua53.can:673 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 else -- ./compiler/lua53.can:674 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +push("push", false) -- ./compiler/lua53.can:676 +end -- ./compiler/lua53.can:676 r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 if hasPush then -- ./compiler/lua53.can:679 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 @@ -1698,7 +1698,7 @@ r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 return r -- ./compiler/lua53.can:684 end, -- ./compiler/lua53.can:684 ["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 end -- ./compiler/lua53.can:689 return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 @@ -1710,7 +1710,7 @@ end, -- ./compiler/lua53.can:695 return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 end, -- ./compiler/lua53.can:699 ["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +for i = 2, # t do -- ./compiler/lua53.can:703 local block = t[i] -- ./compiler/lua53.can:704 if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 @@ -1727,7 +1727,7 @@ end, -- ./compiler/lua53.can:717 ["Call"] = function(t) -- ./compiler/lua53.can:723 if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 else -- ./compiler/lua53.can:728 @@ -1738,7 +1738,7 @@ return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 end -- ./compiler/lua53.can:733 end, -- ./compiler/lua53.can:733 ["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 else -- ./compiler/lua53.can:739 return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 @@ -1761,7 +1761,7 @@ end, -- ./compiler/lua53.can:756 return t[1] -- ./compiler/lua53.can:760 end, -- ./compiler/lua53.can:760 ["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +if t["id"] then -- ./compiler/lua53.can:764 return t["id"] -- ./compiler/lua53.can:765 else -- ./compiler/lua53.can:765 local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 @@ -1782,13 +1782,13 @@ return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 end -- ./compiler/lua53.can:782 end, -- ./compiler/lua53.can:782 ["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 -local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 +local l = {} -- ./compiler/lua53.can:788 while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 table["insert"](l, 1, t) -- ./compiler/lua53.can:790 t = t[1] -- ./compiler/lua53.can:791 end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 for _, e in ipairs(l) do -- ./compiler/lua53.can:794 r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 @@ -1881,10 +1881,10 @@ local function _() -- ./compiler/luajit.can:54 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 lastInputPos = 1 -- ./compiler/lua53.can:5 +local prevLinePos = 1 -- ./compiler/lua53.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 +local lastLine = 1 -- ./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 @@ -1916,10 +1916,10 @@ indentLevel = indentLevel - (1) -- ./compiler/lua53.can:41 return newline() -- ./compiler/lua53.can:42 end -- ./compiler/lua53.can:42 local states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- push stack variable names -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} -- ./compiler/lua53.can:49 -["scope"] = {} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 -} -- list of variables defined in the current scope -- ./compiler/lua53.can:50 +["push"] = {}, -- ./compiler/lua53.can:48 +["destructuring"] = {}, -- ./compiler/lua53.can:49 +["scope"] = {} -- ./compiler/lua53.can:50 +} -- ./compiler/lua53.can:50 local function push(name, state) -- ./compiler/lua53.can:53 table["insert"](states[name], state) -- ./compiler/lua53.can:54 return "" -- ./compiler/lua53.can:55 @@ -1944,7 +1944,7 @@ local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/l table["insert"](scope, var) -- ./compiler/lua53.can:82 return var -- ./compiler/lua53.can:83 end -- ./compiler/lua53.can:83 -local required = {} -- { ["full require expression"] = true, ... } -- ./compiler/lua53.can:87 +local required = {} -- ./compiler/lua53.can:87 local requireStr = "" -- ./compiler/lua53.can:88 local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 @@ -1953,26 +1953,26 @@ requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options[" required[req] = true -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 end -- ./compiler/lua53.can:94 -local loop = { -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"While", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Repeat", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Fornum", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"Forin", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"WhileExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"RepeatExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"FornumExpr", -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -"ForinExpr" -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -} -- loops tags (can contain continue) -- ./compiler/lua53.can:99 -local func = { -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"Function", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"TableCompr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"DoExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"WhileExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"RepeatExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"IfExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"FornumExpr", -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -"ForinExpr" -- function scope tags (can contain push) -- ./compiler/lua53.can:100 -} -- function scope tags (can contain push) -- ./compiler/lua53.can:100 +local loop = { -- ./compiler/lua53.can:99 +"While", -- ./compiler/lua53.can:99 +"Repeat", -- ./compiler/lua53.can:99 +"Fornum", -- ./compiler/lua53.can:99 +"Forin", -- ./compiler/lua53.can:99 +"WhileExpr", -- ./compiler/lua53.can:99 +"RepeatExpr", -- ./compiler/lua53.can:99 +"FornumExpr", -- ./compiler/lua53.can:99 +"ForinExpr" -- ./compiler/lua53.can:99 +} -- ./compiler/lua53.can:99 +local func = { -- ./compiler/lua53.can:100 +"Function", -- ./compiler/lua53.can:100 +"TableCompr", -- ./compiler/lua53.can:100 +"DoExpr", -- ./compiler/lua53.can:100 +"WhileExpr", -- ./compiler/lua53.can:100 +"RepeatExpr", -- ./compiler/lua53.can:100 +"IfExpr", -- ./compiler/lua53.can:100 +"FornumExpr", -- ./compiler/lua53.can:100 +"ForinExpr" -- ./compiler/lua53.can:100 +} -- ./compiler/lua53.can:100 local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 local tagsCheck = {} -- ./compiler/lua53.can:105 @@ -2045,21 +2045,21 @@ lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 end -- ./compiler/lua53.can:176 return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- table.unpack -- ./compiler/lua53.can:182 +local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- append values "toAppend" (multiple values possible) to t -- ./compiler/lua53.can:185 +local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- at the start of loops using continue -- ./compiler/lua53.can:188 +local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- at the start of loops using continue -- ./compiler/lua53.can:191 +local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- to define values from a destructuring assignement -- ./compiler/lua53.can:194 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 local vars = {} -- ./compiler/lua53.can:195 local values = {} -- ./compiler/lua53.can:196 for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 @@ -2135,8 +2135,8 @@ end -- ./compiler/lua53.can:228 end -- ./compiler/lua53.can:228 tags = setmetatable({ -- ./compiler/lua53.can:233 ["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- if the first push is the last statement, it's just a return -- ./compiler/lua53.can:237 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 hasPush = false -- ./compiler/lua53.can:239 end -- ./compiler/lua53.can:239 @@ -2150,7 +2150,7 @@ end -- ./compiler/lua53.can:246 if t[# t] then -- ./compiler/lua53.can:248 r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:251 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 end -- ./compiler/lua53.can:252 return r .. pop("scope") -- ./compiler/lua53.can:254 @@ -2328,7 +2328,7 @@ return r -- ./compiler/lua53.can:379 end, -- ./compiler/lua53.can:379 ["If"] = function(t) -- ./compiler/lua53.can:382 local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- blocks that need to be closed at the end of the if -- ./compiler/lua53.can:384 +local toClose = 0 -- ./compiler/lua53.can:384 local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 if # lets > 0 then -- ./compiler/lua53.can:386 r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 @@ -2412,13 +2412,13 @@ local destructured = {} -- ./compiler/lua53.can:468 local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 local r = "local " .. nameList -- ./compiler/lua53.can:470 if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Nil", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Dots", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Boolean", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"Number", -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -"String" -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 -}) then -- predeclaration doesn't matter here -- ./compiler/lua53.can:472 +if all(t[2], { -- ./compiler/lua53.can:472 +"Nil", -- ./compiler/lua53.can:472 +"Dots", -- ./compiler/lua53.can:472 +"Boolean", -- ./compiler/lua53.can:472 +"Number", -- ./compiler/lua53.can:472 +"String" -- ./compiler/lua53.can:472 +}) then -- ./compiler/lua53.can:472 r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 else -- ./compiler/lua53.can:473 r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 @@ -2512,17 +2512,17 @@ r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 r = r .. (d .. newline()) -- ./compiler/lua53.can:581 end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:583 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 end -- ./compiler/lua53.can:584 local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 if hasPush then -- ./compiler/lua53.can:587 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 else -- ./compiler/lua53.can:588 -push("push", false) -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 -end -- no push here (make sure higher push doesn't affect us) -- ./compiler/lua53.can:590 +push("push", false) -- ./compiler/lua53.can:590 +end -- ./compiler/lua53.can:590 r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- add return only if needed -- ./compiler/lua53.can:593 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 end -- ./compiler/lua53.can:594 pop("push") -- ./compiler/lua53.can:596 @@ -2581,8 +2581,8 @@ local r = "(function()" .. indent() -- ./compiler/lua53.can:672 if hasPush then -- ./compiler/lua53.can:673 r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 else -- ./compiler/lua53.can:674 -push("push", false) -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 -end -- no push here (make sure higher push don't affect us) -- ./compiler/lua53.can:676 +push("push", false) -- ./compiler/lua53.can:676 +end -- ./compiler/lua53.can:676 r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 if hasPush then -- ./compiler/lua53.can:679 r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 @@ -2592,7 +2592,7 @@ r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 return r -- ./compiler/lua53.can:684 end, -- ./compiler/lua53.can:684 ["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- convert final push to return -- ./compiler/lua53.can:688 +if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 end -- ./compiler/lua53.can:689 return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 @@ -2604,7 +2604,7 @@ end, -- ./compiler/lua53.can:695 return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 end, -- ./compiler/lua53.can:699 ["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- convert final pushes to returns -- ./compiler/lua53.can:703 +for i = 2, # t do -- ./compiler/lua53.can:703 local block = t[i] -- ./compiler/lua53.can:704 if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 @@ -2621,7 +2621,7 @@ end, -- ./compiler/lua53.can:717 ["Call"] = function(t) -- ./compiler/lua53.can:723 if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- method call -- ./compiler/lua53.can:726 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 else -- ./compiler/lua53.can:728 @@ -2632,7 +2632,7 @@ return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 end -- ./compiler/lua53.can:733 end, -- ./compiler/lua53.can:733 ["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:738 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 else -- ./compiler/lua53.can:739 return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 @@ -2655,7 +2655,7 @@ end, -- ./compiler/lua53.can:756 return t[1] -- ./compiler/lua53.can:760 end, -- ./compiler/lua53.can:760 ["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- destructing already done before, use parent variable as id -- ./compiler/lua53.can:764 +if t["id"] then -- ./compiler/lua53.can:764 return t["id"] -- ./compiler/lua53.can:765 else -- ./compiler/lua53.can:765 local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 @@ -2676,13 +2676,13 @@ return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 end -- ./compiler/lua53.can:782 end, -- ./compiler/lua53.can:782 ["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) -- ./compiler/lua53.can:787 -local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) -- ./compiler/lua53.can:788 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 +local l = {} -- ./compiler/lua53.can:788 while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 table["insert"](l, 1, t) -- ./compiler/lua53.can:790 t = t[1] -- ./compiler/lua53.can:791 end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- base expr -- ./compiler/lua53.can:793 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 for _, e in ipairs(l) do -- ./compiler/lua53.can:794 r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 @@ -2762,7 +2762,7 @@ 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 +states["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 @@ -2795,1693 +2795,1696 @@ 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 -return 1, 1 -- ./lib/lua-parser/scope.lua:7 -end -- ./lib/lua-parser/scope.lua:7 -local l, lastline = 0, "" -- ./lib/lua-parser/scope.lua:8 +local scope = {} -- ./candran/can-parser/scope.lua:4 +scope["lineno"] = function(s, i) -- ./candran/can-parser/scope.lua:6 +if i == 1 then -- ./candran/can-parser/scope.lua:7 +return 1, 1 -- ./candran/can-parser/scope.lua:7 +end -- ./candran/can-parser/scope.lua:7 +local l, lastline = 0, "" -- ./candran/can-parser/scope.lua:8 s = s:sub(1, i) .. "\ -" -- ./lib/lua-parser/scope.lua:9 +" -- ./candran/can-parser/scope.lua:9 for line in s:gmatch("[^\ ]*[\ -]") do -- ./lib/lua-parser/scope.lua:10 -l = l + 1 -- ./lib/lua-parser/scope.lua:11 -lastline = line -- ./lib/lua-parser/scope.lua:12 -end -- ./lib/lua-parser/scope.lua:12 -local c = lastline:len() - 1 -- ./lib/lua-parser/scope.lua:14 -return l, c ~= 0 and c or 1 -- ./lib/lua-parser/scope.lua:15 -end -- ./lib/lua-parser/scope.lua:15 -scope["new_scope"] = function(env) -- ./lib/lua-parser/scope.lua:18 -if not env["scope"] then -- ./lib/lua-parser/scope.lua:19 -env["scope"] = 0 -- ./lib/lua-parser/scope.lua:20 -else -- ./lib/lua-parser/scope.lua:20 -env["scope"] = env["scope"] + 1 -- ./lib/lua-parser/scope.lua:22 -end -- ./lib/lua-parser/scope.lua:22 -local scope = env["scope"] -- ./lib/lua-parser/scope.lua:24 -env["maxscope"] = scope -- ./lib/lua-parser/scope.lua:25 -env[scope] = {} -- ./lib/lua-parser/scope.lua:26 -env[scope]["label"] = {} -- ./lib/lua-parser/scope.lua:27 -env[scope]["local"] = {} -- ./lib/lua-parser/scope.lua:28 -env[scope]["goto"] = {} -- ./lib/lua-parser/scope.lua:29 -end -- ./lib/lua-parser/scope.lua:29 -scope["begin_scope"] = function(env) -- ./lib/lua-parser/scope.lua:32 -env["scope"] = env["scope"] + 1 -- ./lib/lua-parser/scope.lua:33 -end -- ./lib/lua-parser/scope.lua:33 -scope["end_scope"] = function(env) -- ./lib/lua-parser/scope.lua:36 -env["scope"] = env["scope"] - 1 -- ./lib/lua-parser/scope.lua:37 -end -- ./lib/lua-parser/scope.lua:37 -scope["new_function"] = function(env) -- ./lib/lua-parser/scope.lua:40 -if not env["fscope"] then -- ./lib/lua-parser/scope.lua:41 -env["fscope"] = 0 -- ./lib/lua-parser/scope.lua:42 -else -- ./lib/lua-parser/scope.lua:42 -env["fscope"] = env["fscope"] + 1 -- ./lib/lua-parser/scope.lua:44 -end -- ./lib/lua-parser/scope.lua:44 -local fscope = env["fscope"] -- ./lib/lua-parser/scope.lua:46 -env["function"][fscope] = {} -- ./lib/lua-parser/scope.lua:47 -end -- ./lib/lua-parser/scope.lua:47 -scope["begin_function"] = function(env) -- ./lib/lua-parser/scope.lua:50 -env["fscope"] = env["fscope"] + 1 -- ./lib/lua-parser/scope.lua:51 -end -- ./lib/lua-parser/scope.lua:51 -scope["end_function"] = function(env) -- ./lib/lua-parser/scope.lua:54 -env["fscope"] = env["fscope"] - 1 -- ./lib/lua-parser/scope.lua:55 -end -- ./lib/lua-parser/scope.lua:55 -scope["begin_loop"] = function(env) -- ./lib/lua-parser/scope.lua:58 -if not env["loop"] then -- ./lib/lua-parser/scope.lua:59 -env["loop"] = 1 -- ./lib/lua-parser/scope.lua:60 -else -- ./lib/lua-parser/scope.lua:60 -env["loop"] = env["loop"] + 1 -- ./lib/lua-parser/scope.lua:62 -end -- ./lib/lua-parser/scope.lua:62 -end -- ./lib/lua-parser/scope.lua:62 -scope["end_loop"] = function(env) -- ./lib/lua-parser/scope.lua:66 -env["loop"] = env["loop"] - 1 -- ./lib/lua-parser/scope.lua:67 -end -- ./lib/lua-parser/scope.lua:67 -scope["insideloop"] = function(env) -- ./lib/lua-parser/scope.lua:70 -return env["loop"] and env["loop"] > 0 -- ./lib/lua-parser/scope.lua:71 -end -- ./lib/lua-parser/scope.lua:71 -return scope -- ./lib/lua-parser/scope.lua:74 -end -- ./lib/lua-parser/scope.lua:74 -local scope = _() or scope -- ./lib/lua-parser/scope.lua:78 -package["loaded"]["lib.lua-parser.scope"] = scope or true -- ./lib/lua-parser/scope.lua:79 -local function _() -- ./lib/lua-parser/scope.lua:82 -local scope = require("lib.lua-parser.scope") -- ./lib/lua-parser/validator.lua:4 -local lineno = scope["lineno"] -- ./lib/lua-parser/validator.lua:6 -local new_scope, end_scope = scope["new_scope"], scope["end_scope"] -- ./lib/lua-parser/validator.lua:7 -local new_function, end_function = scope["new_function"], scope["end_function"] -- ./lib/lua-parser/validator.lua:8 -local begin_loop, end_loop = scope["begin_loop"], scope["end_loop"] -- ./lib/lua-parser/validator.lua:9 -local insideloop = scope["insideloop"] -- ./lib/lua-parser/validator.lua:10 -local function syntaxerror(errorinfo, pos, msg) -- ./lib/lua-parser/validator.lua:13 -local l, c = lineno(errorinfo["subject"], pos) -- ./lib/lua-parser/validator.lua:14 -local error_msg = "%s:%d:%d: syntax error, %s" -- ./lib/lua-parser/validator.lua:15 -return string["format"](error_msg, errorinfo["filename"], l, c, msg) -- ./lib/lua-parser/validator.lua:16 -end -- ./lib/lua-parser/validator.lua:16 -local function exist_label(env, scope, stm) -- ./lib/lua-parser/validator.lua:19 -local l = stm[1] -- ./lib/lua-parser/validator.lua:20 -for s = scope, 0, - 1 do -- ./lib/lua-parser/validator.lua:21 -if env[s]["label"][l] then -- ./lib/lua-parser/validator.lua:22 -return true -- ./lib/lua-parser/validator.lua:22 -end -- ./lib/lua-parser/validator.lua:22 -end -- ./lib/lua-parser/validator.lua:22 -return false -- ./lib/lua-parser/validator.lua:24 -end -- ./lib/lua-parser/validator.lua:24 -local function set_label(env, label, pos) -- ./lib/lua-parser/validator.lua:27 -local scope = env["scope"] -- ./lib/lua-parser/validator.lua:28 -local l = env[scope]["label"][label] -- ./lib/lua-parser/validator.lua:29 -if not l then -- ./lib/lua-parser/validator.lua:30 -env[scope]["label"][label] = { -- ./lib/lua-parser/validator.lua:31 -["name"] = label, -- ./lib/lua-parser/validator.lua:31 -["pos"] = pos -- ./lib/lua-parser/validator.lua:31 -} -- ./lib/lua-parser/validator.lua:31 -return true -- ./lib/lua-parser/validator.lua:32 -else -- ./lib/lua-parser/validator.lua:32 -local msg = "label '%s' already defined at line %d" -- ./lib/lua-parser/validator.lua:34 -local line = lineno(env["errorinfo"]["subject"], l["pos"]) -- ./lib/lua-parser/validator.lua:35 -msg = string["format"](msg, label, line) -- ./lib/lua-parser/validator.lua:36 -return nil, syntaxerror(env["errorinfo"], pos, msg) -- ./lib/lua-parser/validator.lua:37 -end -- ./lib/lua-parser/validator.lua:37 -end -- ./lib/lua-parser/validator.lua:37 -local function set_pending_goto(env, stm) -- ./lib/lua-parser/validator.lua:41 -local scope = env["scope"] -- ./lib/lua-parser/validator.lua:42 -table["insert"](env[scope]["goto"], stm) -- ./lib/lua-parser/validator.lua:43 -return true -- ./lib/lua-parser/validator.lua:44 -end -- ./lib/lua-parser/validator.lua:44 -local function verify_pending_gotos(env) -- ./lib/lua-parser/validator.lua:47 -for s = env["maxscope"], 0, - 1 do -- ./lib/lua-parser/validator.lua:48 -for k, v in ipairs(env[s]["goto"]) do -- ./lib/lua-parser/validator.lua:49 -if not exist_label(env, s, v) then -- ./lib/lua-parser/validator.lua:50 -local msg = "no visible label '%s' for " -- ./lib/lua-parser/validator.lua:51 -msg = string["format"](msg, v[1]) -- ./lib/lua-parser/validator.lua:52 -return nil, syntaxerror(env["errorinfo"], v["pos"], msg) -- ./lib/lua-parser/validator.lua:53 -end -- ./lib/lua-parser/validator.lua:53 -end -- ./lib/lua-parser/validator.lua:53 -end -- ./lib/lua-parser/validator.lua:53 -return true -- ./lib/lua-parser/validator.lua:57 -end -- ./lib/lua-parser/validator.lua:57 -local function set_vararg(env, is_vararg) -- ./lib/lua-parser/validator.lua:60 -env["function"][env["fscope"]]["is_vararg"] = is_vararg -- ./lib/lua-parser/validator.lua:61 -end -- ./lib/lua-parser/validator.lua:61 -local traverse_stm, traverse_exp, traverse_var -- ./lib/lua-parser/validator.lua:64 -local traverse_block, traverse_explist, traverse_varlist, traverse_parlist -- ./lib/lua-parser/validator.lua:65 -traverse_parlist = function(env, parlist) -- ./lib/lua-parser/validator.lua:67 -local len = # parlist -- ./lib/lua-parser/validator.lua:68 -local is_vararg = false -- ./lib/lua-parser/validator.lua:69 -if len > 0 and parlist[len]["tag"] == "Dots" then -- ./lib/lua-parser/validator.lua:70 -is_vararg = true -- ./lib/lua-parser/validator.lua:71 -end -- ./lib/lua-parser/validator.lua:71 -set_vararg(env, is_vararg) -- ./lib/lua-parser/validator.lua:73 -return true -- ./lib/lua-parser/validator.lua:74 -end -- ./lib/lua-parser/validator.lua:74 -local function traverse_function(env, exp) -- ./lib/lua-parser/validator.lua:77 -new_function(env) -- ./lib/lua-parser/validator.lua:78 -new_scope(env) -- ./lib/lua-parser/validator.lua:79 -local status, msg = traverse_parlist(env, exp[1]) -- ./lib/lua-parser/validator.lua:80 -if not status then -- ./lib/lua-parser/validator.lua:81 -return status, msg -- ./lib/lua-parser/validator.lua:81 -end -- ./lib/lua-parser/validator.lua:81 -status, msg = traverse_block(env, exp[2]) -- ./lib/lua-parser/validator.lua:82 -if not status then -- ./lib/lua-parser/validator.lua:83 -return status, msg -- ./lib/lua-parser/validator.lua:83 -end -- ./lib/lua-parser/validator.lua:83 -end_scope(env) -- ./lib/lua-parser/validator.lua:84 -end_function(env) -- ./lib/lua-parser/validator.lua:85 -return true -- ./lib/lua-parser/validator.lua:86 -end -- ./lib/lua-parser/validator.lua:86 -local function traverse_tablecompr(env, exp) -- ./lib/lua-parser/validator.lua:89 -new_function(env) -- ./lib/lua-parser/validator.lua:90 -new_scope(env) -- ./lib/lua-parser/validator.lua:91 -local status, msg = traverse_block(env, exp[1]) -- ./lib/lua-parser/validator.lua:92 -if not status then -- ./lib/lua-parser/validator.lua:93 -return status, msg -- ./lib/lua-parser/validator.lua:93 -end -- ./lib/lua-parser/validator.lua:93 -end_scope(env) -- ./lib/lua-parser/validator.lua:94 -end_function(env) -- ./lib/lua-parser/validator.lua:95 -return true -- ./lib/lua-parser/validator.lua:96 -end -- ./lib/lua-parser/validator.lua:96 -local function traverse_statexpr(env, exp) -- ./lib/lua-parser/validator.lua:99 -new_function(env) -- ./lib/lua-parser/validator.lua:100 -new_scope(env) -- ./lib/lua-parser/validator.lua:101 -exp["tag"] = exp["tag"]:gsub("Expr$", "") -- ./lib/lua-parser/validator.lua:102 -local status, msg = traverse_stm(env, exp) -- ./lib/lua-parser/validator.lua:103 -exp["tag"] = exp["tag"] .. "Expr" -- ./lib/lua-parser/validator.lua:104 -if not status then -- ./lib/lua-parser/validator.lua:105 -return status, msg -- ./lib/lua-parser/validator.lua:105 -end -- ./lib/lua-parser/validator.lua:105 -end_scope(env) -- ./lib/lua-parser/validator.lua:106 -end_function(env) -- ./lib/lua-parser/validator.lua:107 -return true -- ./lib/lua-parser/validator.lua:108 -end -- ./lib/lua-parser/validator.lua:108 -local function traverse_op(env, exp) -- ./lib/lua-parser/validator.lua:111 -local status, msg = traverse_exp(env, exp[2]) -- ./lib/lua-parser/validator.lua:112 -if not status then -- ./lib/lua-parser/validator.lua:113 -return status, msg -- ./lib/lua-parser/validator.lua:113 -end -- ./lib/lua-parser/validator.lua:113 -if exp[3] then -- ./lib/lua-parser/validator.lua:114 -status, msg = traverse_exp(env, exp[3]) -- ./lib/lua-parser/validator.lua:115 -if not status then -- ./lib/lua-parser/validator.lua:116 -return status, msg -- ./lib/lua-parser/validator.lua:116 -end -- ./lib/lua-parser/validator.lua:116 -end -- ./lib/lua-parser/validator.lua:116 -return true -- ./lib/lua-parser/validator.lua:118 -end -- ./lib/lua-parser/validator.lua:118 -local function traverse_paren(env, exp) -- ./lib/lua-parser/validator.lua:121 -local status, msg = traverse_exp(env, exp[1]) -- ./lib/lua-parser/validator.lua:122 -if not status then -- ./lib/lua-parser/validator.lua:123 -return status, msg -- ./lib/lua-parser/validator.lua:123 -end -- ./lib/lua-parser/validator.lua:123 -return true -- ./lib/lua-parser/validator.lua:124 -end -- ./lib/lua-parser/validator.lua:124 -local function traverse_table(env, fieldlist) -- ./lib/lua-parser/validator.lua:127 -for k, v in ipairs(fieldlist) do -- ./lib/lua-parser/validator.lua:128 -local tag = v["tag"] -- ./lib/lua-parser/validator.lua:129 -if tag == "Pair" then -- ./lib/lua-parser/validator.lua:130 -local status, msg = traverse_exp(env, v[1]) -- ./lib/lua-parser/validator.lua:131 -if not status then -- ./lib/lua-parser/validator.lua:132 -return status, msg -- ./lib/lua-parser/validator.lua:132 -end -- ./lib/lua-parser/validator.lua:132 -status, msg = traverse_exp(env, v[2]) -- ./lib/lua-parser/validator.lua:133 -if not status then -- ./lib/lua-parser/validator.lua:134 -return status, msg -- ./lib/lua-parser/validator.lua:134 -end -- ./lib/lua-parser/validator.lua:134 -else -- ./lib/lua-parser/validator.lua:134 -local status, msg = traverse_exp(env, v) -- ./lib/lua-parser/validator.lua:136 -if not status then -- ./lib/lua-parser/validator.lua:137 -return status, msg -- ./lib/lua-parser/validator.lua:137 -end -- ./lib/lua-parser/validator.lua:137 -end -- ./lib/lua-parser/validator.lua:137 -end -- ./lib/lua-parser/validator.lua:137 -return true -- ./lib/lua-parser/validator.lua:140 -end -- ./lib/lua-parser/validator.lua:140 -local function traverse_vararg(env, exp) -- ./lib/lua-parser/validator.lua:143 -if not env["function"][env["fscope"]]["is_vararg"] then -- ./lib/lua-parser/validator.lua:144 -local msg = "cannot use '...' outside a vararg function" -- ./lib/lua-parser/validator.lua:145 -return nil, syntaxerror(env["errorinfo"], exp["pos"], msg) -- ./lib/lua-parser/validator.lua:146 -end -- ./lib/lua-parser/validator.lua:146 -return true -- ./lib/lua-parser/validator.lua:148 -end -- ./lib/lua-parser/validator.lua:148 -local function traverse_call(env, call) -- ./lib/lua-parser/validator.lua:151 -local status, msg = traverse_exp(env, call[1]) -- ./lib/lua-parser/validator.lua:152 -if not status then -- ./lib/lua-parser/validator.lua:153 -return status, msg -- ./lib/lua-parser/validator.lua:153 -end -- ./lib/lua-parser/validator.lua:153 -for i = 2, # call do -- ./lib/lua-parser/validator.lua:154 -status, msg = traverse_exp(env, call[i]) -- ./lib/lua-parser/validator.lua:155 -if not status then -- ./lib/lua-parser/validator.lua:156 -return status, msg -- ./lib/lua-parser/validator.lua:156 -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_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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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_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 -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 -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 -elseif tag == "DestructuringId" then -- ./lib/lua-parser/validator.lua:307 -return traverse_table(env, var) -- ./lib/lua-parser/validator.lua:308 -else -- ./lib/lua-parser/validator.lua:308 -error("expecting a variable, but got a " .. tag) -- ./lib/lua-parser/validator.lua:310 -end -- ./lib/lua-parser/validator.lua:310 -end -- ./lib/lua-parser/validator.lua:310 -traverse_varlist = function(env, varlist) -- ./lib/lua-parser/validator.lua:314 -for k, v in ipairs(varlist) do -- ./lib/lua-parser/validator.lua:315 -local status, msg = traverse_var(env, v) -- ./lib/lua-parser/validator.lua:316 -if not status then -- ./lib/lua-parser/validator.lua:317 -return status, msg -- ./lib/lua-parser/validator.lua:317 -end -- ./lib/lua-parser/validator.lua:317 -end -- ./lib/lua-parser/validator.lua:317 -return true -- ./lib/lua-parser/validator.lua:319 -end -- ./lib/lua-parser/validator.lua:319 -local function traverse_methodstub(env, var) -- ./lib/lua-parser/validator.lua:322 -local status, msg = traverse_exp(env, var[1]) -- ./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 -status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:325 -if not status then -- ./lib/lua-parser/validator.lua:326 -return status, msg -- ./lib/lua-parser/validator.lua:326 -end -- ./lib/lua-parser/validator.lua:326 -return true -- ./lib/lua-parser/validator.lua:327 -end -- ./lib/lua-parser/validator.lua:327 -local function traverse_safeindex(env, var) -- ./lib/lua-parser/validator.lua:330 -local status, msg = traverse_exp(env, var[1]) -- ./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 -status, msg = traverse_exp(env, var[2]) -- ./lib/lua-parser/validator.lua:333 -if not status then -- ./lib/lua-parser/validator.lua:334 -return status, msg -- ./lib/lua-parser/validator.lua:334 -end -- ./lib/lua-parser/validator.lua:334 -return true -- ./lib/lua-parser/validator.lua:335 -end -- ./lib/lua-parser/validator.lua:335 -traverse_exp = function(env, exp) -- ./lib/lua-parser/validator.lua:338 -local tag = exp["tag"] -- ./lib/lua-parser/validator.lua:339 -if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- `String{ } -- ./lib/lua-parser/validator.lua:343 -return true -- ./lib/lua-parser/validator.lua:344 -elseif tag == "Dots" then -- ./lib/lua-parser/validator.lua:345 -return traverse_vararg(env, exp) -- ./lib/lua-parser/validator.lua:346 -elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } -- ./lib/lua-parser/validator.lua:347 -return traverse_function(env, exp) -- ./lib/lua-parser/validator.lua:348 -elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } -- ./lib/lua-parser/validator.lua:349 -return traverse_table(env, exp) -- ./lib/lua-parser/validator.lua:350 -elseif tag == "Op" then -- `Op{ opid expr expr? } -- ./lib/lua-parser/validator.lua:351 -return traverse_op(env, exp) -- ./lib/lua-parser/validator.lua:352 -elseif tag == "Paren" then -- `Paren{ expr } -- ./lib/lua-parser/validator.lua:353 -return traverse_paren(env, exp) -- ./lib/lua-parser/validator.lua:354 -elseif tag == "Call" or tag == "SafeCall" then -- `(Safe)Call{ expr expr* } -- ./lib/lua-parser/validator.lua:355 -return traverse_call(env, exp) -- ./lib/lua-parser/validator.lua:356 -elseif tag == "Id" or tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/validator.lua:358 -return traverse_var(env, exp) -- ./lib/lua-parser/validator.lua:359 -elseif tag == "SafeIndex" then -- `SafeIndex{ expr expr } -- ./lib/lua-parser/validator.lua:360 -return traverse_safeindex(env, exp) -- ./lib/lua-parser/validator.lua:361 -elseif tag == "TableCompr" then -- `TableCompr{ block } -- ./lib/lua-parser/validator.lua:362 -return traverse_tablecompr(env, exp) -- ./lib/lua-parser/validator.lua:363 -elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- `(Safe)MethodStub{ expr expr } -- ./lib/lua-parser/validator.lua:364 -return traverse_methodstub(env, exp) -- ./lib/lua-parser/validator.lua:365 -elseif tag:match("Expr$") then -- `StatExpr{ ... } -- ./lib/lua-parser/validator.lua:366 -return traverse_statexpr(env, exp) -- ./lib/lua-parser/validator.lua:367 -else -- ./lib/lua-parser/validator.lua:367 -error("expecting an expression, but got a " .. tag) -- ./lib/lua-parser/validator.lua:369 -end -- ./lib/lua-parser/validator.lua:369 -end -- ./lib/lua-parser/validator.lua:369 -traverse_explist = function(env, explist) -- ./lib/lua-parser/validator.lua:373 -for k, v in ipairs(explist) do -- ./lib/lua-parser/validator.lua:374 -local status, msg = traverse_exp(env, v) -- ./lib/lua-parser/validator.lua:375 -if not status then -- ./lib/lua-parser/validator.lua:376 -return status, msg -- ./lib/lua-parser/validator.lua:376 -end -- ./lib/lua-parser/validator.lua:376 -end -- ./lib/lua-parser/validator.lua:376 -return true -- ./lib/lua-parser/validator.lua:378 -end -- ./lib/lua-parser/validator.lua:378 -traverse_stm = function(env, stm) -- ./lib/lua-parser/validator.lua:381 -local tag = stm["tag"] -- ./lib/lua-parser/validator.lua:382 -if tag == "Do" then -- `Do{ stat* } -- ./lib/lua-parser/validator.lua:383 -return traverse_block(env, stm) -- ./lib/lua-parser/validator.lua:384 -elseif tag == "Set" then -- `Set{ {lhs+} (opid? = opid?)? {expr+} } -- ./lib/lua-parser/validator.lua:385 -return traverse_assignment(env, stm) -- ./lib/lua-parser/validator.lua:386 -elseif tag == "While" then -- `While{ expr block } -- ./lib/lua-parser/validator.lua:387 -return traverse_while(env, stm) -- ./lib/lua-parser/validator.lua:388 -elseif tag == "Repeat" then -- `Repeat{ block expr } -- ./lib/lua-parser/validator.lua:389 -return traverse_repeat(env, stm) -- ./lib/lua-parser/validator.lua:390 -elseif tag == "If" then -- `If{ (expr block)+ block? } -- ./lib/lua-parser/validator.lua:391 -return traverse_if(env, stm) -- ./lib/lua-parser/validator.lua:392 -elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } -- ./lib/lua-parser/validator.lua:393 -return traverse_fornum(env, stm) -- ./lib/lua-parser/validator.lua:394 -elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } -- ./lib/lua-parser/validator.lua:395 -return traverse_forin(env, stm) -- ./lib/lua-parser/validator.lua:396 -elseif tag == "Local" or tag == "Let" then -- `Let{ {ident+} {expr+}? } -- ./lib/lua-parser/validator.lua:398 -return traverse_let(env, stm) -- ./lib/lua-parser/validator.lua:399 -elseif tag == "Localrec" then -- `Localrec{ ident expr } -- ./lib/lua-parser/validator.lua:400 -return traverse_letrec(env, stm) -- ./lib/lua-parser/validator.lua:401 -elseif tag == "Goto" then -- `Goto{ } -- ./lib/lua-parser/validator.lua:402 -return traverse_goto(env, stm) -- ./lib/lua-parser/validator.lua:403 -elseif tag == "Label" then -- `Label{ } -- ./lib/lua-parser/validator.lua:404 -return traverse_label(env, stm) -- ./lib/lua-parser/validator.lua:405 -elseif tag == "Return" then -- `Return{ * } -- ./lib/lua-parser/validator.lua:406 -return traverse_return(env, stm) -- ./lib/lua-parser/validator.lua:407 -elseif tag == "Break" then -- ./lib/lua-parser/validator.lua:408 -return traverse_break(env, stm) -- ./lib/lua-parser/validator.lua:409 -elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/validator.lua:410 -return traverse_call(env, stm) -- ./lib/lua-parser/validator.lua:411 -elseif tag == "Continue" then -- ./lib/lua-parser/validator.lua:412 -return traverse_continue(env, stm) -- ./lib/lua-parser/validator.lua:413 -elseif tag == "Push" then -- `Push{ * } -- ./lib/lua-parser/validator.lua:414 -return traverse_push(env, stm) -- ./lib/lua-parser/validator.lua:415 -else -- ./lib/lua-parser/validator.lua:415 -error("expecting a statement, but got a " .. tag) -- ./lib/lua-parser/validator.lua:417 -end -- ./lib/lua-parser/validator.lua:417 -end -- ./lib/lua-parser/validator.lua:417 -traverse_block = function(env, block) -- ./lib/lua-parser/validator.lua:421 -local l = {} -- ./lib/lua-parser/validator.lua:422 -new_scope(env) -- ./lib/lua-parser/validator.lua:423 -for k, v in ipairs(block) do -- ./lib/lua-parser/validator.lua:424 -local status, msg = traverse_stm(env, v) -- ./lib/lua-parser/validator.lua:425 -if not status then -- ./lib/lua-parser/validator.lua:426 -return status, msg -- ./lib/lua-parser/validator.lua:426 -end -- ./lib/lua-parser/validator.lua:426 -end -- ./lib/lua-parser/validator.lua:426 -end_scope(env) -- ./lib/lua-parser/validator.lua:428 -return true -- ./lib/lua-parser/validator.lua:429 -end -- ./lib/lua-parser/validator.lua:429 -local function traverse(ast, errorinfo) -- ./lib/lua-parser/validator.lua:433 -assert(type(ast) == "table") -- ./lib/lua-parser/validator.lua:434 -assert(type(errorinfo) == "table") -- ./lib/lua-parser/validator.lua:435 -local env = { -- ./lib/lua-parser/validator.lua:436 -["errorinfo"] = errorinfo, -- ./lib/lua-parser/validator.lua:436 -["function"] = {} -- ./lib/lua-parser/validator.lua:436 -} -- ./lib/lua-parser/validator.lua:436 -new_function(env) -- ./lib/lua-parser/validator.lua:437 -set_vararg(env, true) -- ./lib/lua-parser/validator.lua:438 -local status, msg = traverse_block(env, ast) -- ./lib/lua-parser/validator.lua:439 -if not status then -- ./lib/lua-parser/validator.lua:440 -return status, msg -- ./lib/lua-parser/validator.lua:440 -end -- ./lib/lua-parser/validator.lua:440 -end_function(env) -- ./lib/lua-parser/validator.lua:441 -status, msg = verify_pending_gotos(env) -- ./lib/lua-parser/validator.lua:442 -if not status then -- ./lib/lua-parser/validator.lua:443 -return status, msg -- ./lib/lua-parser/validator.lua:443 -end -- ./lib/lua-parser/validator.lua:443 -return ast -- ./lib/lua-parser/validator.lua:444 -end -- ./lib/lua-parser/validator.lua:444 -return { -- ./lib/lua-parser/validator.lua:447 -["validate"] = traverse, -- ./lib/lua-parser/validator.lua:447 -["syntaxerror"] = syntaxerror -- ./lib/lua-parser/validator.lua:447 -} -- ./lib/lua-parser/validator.lua:447 -end -- ./lib/lua-parser/validator.lua:447 -local validator = _() or validator -- ./lib/lua-parser/validator.lua:451 -package["loaded"]["lib.lua-parser.validator"] = validator or true -- ./lib/lua-parser/validator.lua:452 -local function _() -- ./lib/lua-parser/validator.lua:455 -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 -local function iscntrl(x) -- ./lib/lua-parser/pp.lua:9 -if (x >= 0 and x <= 31) or (x == 127) then -- ./lib/lua-parser/pp.lua:10 -return true -- ./lib/lua-parser/pp.lua:10 -end -- ./lib/lua-parser/pp.lua:10 -return false -- ./lib/lua-parser/pp.lua:11 -end -- ./lib/lua-parser/pp.lua:11 -local function isprint(x) -- ./lib/lua-parser/pp.lua:14 -return not iscntrl(x) -- ./lib/lua-parser/pp.lua:15 -end -- ./lib/lua-parser/pp.lua:15 -local function fixed_string(str) -- ./lib/lua-parser/pp.lua:18 -local new_str = "" -- ./lib/lua-parser/pp.lua:19 -for i = 1, string["len"](str) do -- ./lib/lua-parser/pp.lua:20 -char = string["byte"](str, i) -- ./lib/lua-parser/pp.lua:21 -if char == 34 then -- ./lib/lua-parser/pp.lua:22 -new_str = new_str .. string["format"]("\\\"") -- ./lib/lua-parser/pp.lua:22 -elseif char == 92 then -- ./lib/lua-parser/pp.lua:23 -new_str = new_str .. string["format"]("\\\\") -- ./lib/lua-parser/pp.lua:23 -elseif char == 7 then -- ./lib/lua-parser/pp.lua:24 -new_str = new_str .. string["format"]("\\a") -- ./lib/lua-parser/pp.lua:24 -elseif char == 8 then -- ./lib/lua-parser/pp.lua:25 -new_str = new_str .. string["format"]("\\b") -- ./lib/lua-parser/pp.lua:25 -elseif char == 12 then -- ./lib/lua-parser/pp.lua:26 -new_str = new_str .. string["format"]("\\f") -- ./lib/lua-parser/pp.lua:26 -elseif char == 10 then -- ./lib/lua-parser/pp.lua:27 -new_str = new_str .. string["format"]("\\n") -- ./lib/lua-parser/pp.lua:27 -elseif char == 13 then -- ./lib/lua-parser/pp.lua:28 -new_str = new_str .. string["format"]("\\r") -- ./lib/lua-parser/pp.lua:28 -elseif char == 9 then -- ./lib/lua-parser/pp.lua:29 -new_str = new_str .. string["format"]("\\t") -- ./lib/lua-parser/pp.lua:29 -elseif char == 11 then -- ./lib/lua-parser/pp.lua:30 -new_str = new_str .. string["format"]("\\v") -- ./lib/lua-parser/pp.lua:30 -else -- ./lib/lua-parser/pp.lua:30 -if isprint(char) then -- ./lib/lua-parser/pp.lua:32 -new_str = new_str .. string["format"]("%c", char) -- ./lib/lua-parser/pp.lua:33 -else -- ./lib/lua-parser/pp.lua:33 -new_str = new_str .. string["format"]("\\%03d", char) -- ./lib/lua-parser/pp.lua:35 -end -- ./lib/lua-parser/pp.lua:35 -end -- ./lib/lua-parser/pp.lua:35 -end -- ./lib/lua-parser/pp.lua:35 -return new_str -- ./lib/lua-parser/pp.lua:39 -end -- ./lib/lua-parser/pp.lua:39 -local function name2str(name) -- ./lib/lua-parser/pp.lua:42 -return string["format"]("\"%s\"", name) -- ./lib/lua-parser/pp.lua:43 -end -- ./lib/lua-parser/pp.lua:43 -local function boolean2str(b) -- ./lib/lua-parser/pp.lua:46 -return string["format"]("\"%s\"", tostring(b)) -- ./lib/lua-parser/pp.lua:47 -end -- ./lib/lua-parser/pp.lua:47 -local function number2str(n) -- ./lib/lua-parser/pp.lua:50 -return string["format"]("\"%s\"", tostring(n)) -- ./lib/lua-parser/pp.lua:51 -end -- ./lib/lua-parser/pp.lua:51 -local function string2str(s) -- ./lib/lua-parser/pp.lua:54 -return string["format"]("\"%s\"", fixed_string(s)) -- ./lib/lua-parser/pp.lua:55 -end -- ./lib/lua-parser/pp.lua:55 -var2str = function(var) -- ./lib/lua-parser/pp.lua:58 -local tag = var["tag"] -- ./lib/lua-parser/pp.lua:59 -local str = "`" .. tag -- ./lib/lua-parser/pp.lua:60 -if tag == "Id" then -- `Id{ } -- ./lib/lua-parser/pp.lua:61 -str = str .. " " .. name2str(var[1]) -- ./lib/lua-parser/pp.lua:62 -elseif tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/pp.lua:63 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:64 -str = str .. exp2str(var[1]) .. ", " -- ./lib/lua-parser/pp.lua:65 -str = str .. exp2str(var[2]) -- ./lib/lua-parser/pp.lua:66 -str = str .. " }" -- ./lib/lua-parser/pp.lua:67 -else -- ./lib/lua-parser/pp.lua:67 -error("expecting a variable, but got a " .. tag) -- ./lib/lua-parser/pp.lua:69 -end -- ./lib/lua-parser/pp.lua:69 -return str -- ./lib/lua-parser/pp.lua:71 -end -- ./lib/lua-parser/pp.lua:71 -varlist2str = function(varlist) -- ./lib/lua-parser/pp.lua:74 -local l = {} -- ./lib/lua-parser/pp.lua:75 -for k, v in ipairs(varlist) do -- ./lib/lua-parser/pp.lua:76 -l[k] = var2str(v) -- ./lib/lua-parser/pp.lua:77 -end -- ./lib/lua-parser/pp.lua:77 -return "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:79 -end -- ./lib/lua-parser/pp.lua:79 -parlist2str = function(parlist) -- ./lib/lua-parser/pp.lua:82 -local l = {} -- ./lib/lua-parser/pp.lua:83 -local len = # parlist -- ./lib/lua-parser/pp.lua:84 -local is_vararg = false -- ./lib/lua-parser/pp.lua:85 -if len > 0 and parlist[len]["tag"] == "Dots" then -- ./lib/lua-parser/pp.lua:86 -is_vararg = true -- ./lib/lua-parser/pp.lua:87 -len = len - 1 -- ./lib/lua-parser/pp.lua:88 -end -- ./lib/lua-parser/pp.lua:88 -local i = 1 -- ./lib/lua-parser/pp.lua:90 -while i <= len do -- ./lib/lua-parser/pp.lua:91 -l[i] = var2str(parlist[i]) -- ./lib/lua-parser/pp.lua:92 -i = i + 1 -- ./lib/lua-parser/pp.lua:93 -end -- ./lib/lua-parser/pp.lua:93 -if is_vararg then -- ./lib/lua-parser/pp.lua:95 -l[i] = "`" .. parlist[i]["tag"] -- ./lib/lua-parser/pp.lua:96 -end -- ./lib/lua-parser/pp.lua:96 -return "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:98 -end -- ./lib/lua-parser/pp.lua:98 -fieldlist2str = function(fieldlist) -- ./lib/lua-parser/pp.lua:101 -local l = {} -- ./lib/lua-parser/pp.lua:102 -for k, v in ipairs(fieldlist) do -- ./lib/lua-parser/pp.lua:103 -local tag = v["tag"] -- ./lib/lua-parser/pp.lua:104 -if tag == "Pair" then -- `Pair{ expr expr } -- ./lib/lua-parser/pp.lua:105 -l[k] = "`" .. tag .. "{ " -- ./lib/lua-parser/pp.lua:106 -l[k] = l[k] .. exp2str(v[1]) .. ", " .. exp2str(v[2]) -- ./lib/lua-parser/pp.lua:107 -l[k] = l[k] .. " }" -- ./lib/lua-parser/pp.lua:108 -else -- ./lib/lua-parser/pp.lua:108 -l[k] = exp2str(v) -- ./lib/lua-parser/pp.lua:110 -end -- ./lib/lua-parser/pp.lua:110 -end -- ./lib/lua-parser/pp.lua:110 -if # l > 0 then -- ./lib/lua-parser/pp.lua:113 -return "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:114 -else -- ./lib/lua-parser/pp.lua:114 -return "" -- ./lib/lua-parser/pp.lua:116 -end -- ./lib/lua-parser/pp.lua:116 -end -- ./lib/lua-parser/pp.lua:116 -exp2str = function(exp) -- ./lib/lua-parser/pp.lua:120 -local tag = exp["tag"] -- ./lib/lua-parser/pp.lua:121 -local str = "`" .. tag -- ./lib/lua-parser/pp.lua:122 -if tag == "Nil" or tag == "Dots" then -- ./lib/lua-parser/pp.lua:124 - -- `Boolean{ } -- ./lib/lua-parser/pp.lua:125 -elseif tag == "Boolean" then -- `Boolean{ } -- ./lib/lua-parser/pp.lua:125 -str = str .. " " .. boolean2str(exp[1]) -- ./lib/lua-parser/pp.lua:126 -elseif tag == "Number" then -- `Number{ } -- ./lib/lua-parser/pp.lua:127 -str = str .. " " .. number2str(exp[1]) -- ./lib/lua-parser/pp.lua:128 -elseif tag == "String" then -- `String{ } -- ./lib/lua-parser/pp.lua:129 -str = str .. " " .. string2str(exp[1]) -- ./lib/lua-parser/pp.lua:130 -elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } -- ./lib/lua-parser/pp.lua:131 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:132 -str = str .. parlist2str(exp[1]) .. ", " -- ./lib/lua-parser/pp.lua:133 -str = str .. block2str(exp[2]) -- ./lib/lua-parser/pp.lua:134 -str = str .. " }" -- ./lib/lua-parser/pp.lua:135 -elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } -- ./lib/lua-parser/pp.lua:136 -str = str .. fieldlist2str(exp) -- ./lib/lua-parser/pp.lua:137 -elseif tag == "Op" then -- `Op{ opid expr expr? } -- ./lib/lua-parser/pp.lua:138 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:139 -str = str .. name2str(exp[1]) .. ", " -- ./lib/lua-parser/pp.lua:140 -str = str .. exp2str(exp[2]) -- ./lib/lua-parser/pp.lua:141 -if exp[3] then -- ./lib/lua-parser/pp.lua:142 -str = str .. ", " .. exp2str(exp[3]) -- ./lib/lua-parser/pp.lua:143 -end -- ./lib/lua-parser/pp.lua:143 -str = str .. " }" -- ./lib/lua-parser/pp.lua:145 -elseif tag == "Paren" then -- `Paren{ expr } -- ./lib/lua-parser/pp.lua:146 -str = str .. "{ " .. exp2str(exp[1]) .. " }" -- ./lib/lua-parser/pp.lua:147 -elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/pp.lua:148 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:149 -str = str .. exp2str(exp[1]) -- ./lib/lua-parser/pp.lua:150 -if exp[2] then -- ./lib/lua-parser/pp.lua:151 -for i = 2, # exp do -- ./lib/lua-parser/pp.lua:152 -str = str .. ", " .. exp2str(exp[i]) -- ./lib/lua-parser/pp.lua:153 -end -- ./lib/lua-parser/pp.lua:153 -end -- ./lib/lua-parser/pp.lua:153 -str = str .. " }" -- ./lib/lua-parser/pp.lua:156 -elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } -- ./lib/lua-parser/pp.lua:157 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:158 -str = str .. exp2str(exp[1]) .. ", " -- ./lib/lua-parser/pp.lua:159 -str = str .. exp2str(exp[2]) -- ./lib/lua-parser/pp.lua:160 -if exp[3] then -- ./lib/lua-parser/pp.lua:161 -for i = 3, # exp do -- ./lib/lua-parser/pp.lua:162 -str = str .. ", " .. exp2str(exp[i]) -- ./lib/lua-parser/pp.lua:163 -end -- ./lib/lua-parser/pp.lua:163 -end -- ./lib/lua-parser/pp.lua:163 -str = str .. " }" -- ./lib/lua-parser/pp.lua:166 -elseif tag == "Id" or tag == "Index" then -- `Index{ expr expr } -- ./lib/lua-parser/pp.lua:168 -str = var2str(exp) -- ./lib/lua-parser/pp.lua:169 -else -- ./lib/lua-parser/pp.lua:169 -error("expecting an expression, but got a " .. tag) -- ./lib/lua-parser/pp.lua:171 -end -- ./lib/lua-parser/pp.lua:171 -return str -- ./lib/lua-parser/pp.lua:173 -end -- ./lib/lua-parser/pp.lua:173 -explist2str = function(explist) -- ./lib/lua-parser/pp.lua:176 -local l = {} -- ./lib/lua-parser/pp.lua:177 -for k, v in ipairs(explist) do -- ./lib/lua-parser/pp.lua:178 -l[k] = exp2str(v) -- ./lib/lua-parser/pp.lua:179 -end -- ./lib/lua-parser/pp.lua:179 -if # l > 0 then -- ./lib/lua-parser/pp.lua:181 -return "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:182 -else -- ./lib/lua-parser/pp.lua:182 -return "" -- ./lib/lua-parser/pp.lua:184 -end -- ./lib/lua-parser/pp.lua:184 -end -- ./lib/lua-parser/pp.lua:184 -stm2str = function(stm) -- ./lib/lua-parser/pp.lua:188 -local tag = stm["tag"] -- ./lib/lua-parser/pp.lua:189 -local str = "`" .. tag -- ./lib/lua-parser/pp.lua:190 -if tag == "Do" then -- `Do{ stat* } -- ./lib/lua-parser/pp.lua:191 -local l = {} -- ./lib/lua-parser/pp.lua:192 -for k, v in ipairs(stm) do -- ./lib/lua-parser/pp.lua:193 -l[k] = stm2str(v) -- ./lib/lua-parser/pp.lua:194 -end -- ./lib/lua-parser/pp.lua:194 -str = str .. "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:196 -elseif tag == "Set" then -- `Set{ {lhs+} {expr+} } -- ./lib/lua-parser/pp.lua:197 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:198 -str = str .. varlist2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:199 -str = str .. explist2str(stm[2]) -- ./lib/lua-parser/pp.lua:200 -str = str .. " }" -- ./lib/lua-parser/pp.lua:201 -elseif tag == "While" then -- `While{ expr block } -- ./lib/lua-parser/pp.lua:202 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:203 -str = str .. exp2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:204 -str = str .. block2str(stm[2]) -- ./lib/lua-parser/pp.lua:205 -str = str .. " }" -- ./lib/lua-parser/pp.lua:206 -elseif tag == "Repeat" then -- `Repeat{ block expr } -- ./lib/lua-parser/pp.lua:207 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:208 -str = str .. block2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:209 -str = str .. exp2str(stm[2]) -- ./lib/lua-parser/pp.lua:210 -str = str .. " }" -- ./lib/lua-parser/pp.lua:211 -elseif tag == "If" then -- `If{ (expr block)+ block? } -- ./lib/lua-parser/pp.lua:212 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:213 -local len = # stm -- ./lib/lua-parser/pp.lua:214 -if len % 2 == 0 then -- ./lib/lua-parser/pp.lua:215 -local l = {} -- ./lib/lua-parser/pp.lua:216 -for i = 1, len - 2, 2 do -- ./lib/lua-parser/pp.lua:217 -str = str .. exp2str(stm[i]) .. ", " .. block2str(stm[i + 1]) .. ", " -- ./lib/lua-parser/pp.lua:218 -end -- ./lib/lua-parser/pp.lua:218 -str = str .. exp2str(stm[len - 1]) .. ", " .. block2str(stm[len]) -- ./lib/lua-parser/pp.lua:220 -else -- ./lib/lua-parser/pp.lua:220 -local l = {} -- ./lib/lua-parser/pp.lua:222 -for i = 1, len - 3, 2 do -- ./lib/lua-parser/pp.lua:223 -str = str .. exp2str(stm[i]) .. ", " .. block2str(stm[i + 1]) .. ", " -- ./lib/lua-parser/pp.lua:224 -end -- ./lib/lua-parser/pp.lua:224 -str = str .. exp2str(stm[len - 2]) .. ", " .. block2str(stm[len - 1]) .. ", " -- ./lib/lua-parser/pp.lua:226 -str = str .. block2str(stm[len]) -- ./lib/lua-parser/pp.lua:227 -end -- ./lib/lua-parser/pp.lua:227 -str = str .. " }" -- ./lib/lua-parser/pp.lua:229 -elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } -- ./lib/lua-parser/pp.lua:230 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:231 -str = str .. var2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:232 -str = str .. exp2str(stm[2]) .. ", " -- ./lib/lua-parser/pp.lua:233 -str = str .. exp2str(stm[3]) .. ", " -- ./lib/lua-parser/pp.lua:234 -if stm[5] then -- ./lib/lua-parser/pp.lua:235 -str = str .. exp2str(stm[4]) .. ", " -- ./lib/lua-parser/pp.lua:236 -str = str .. block2str(stm[5]) -- ./lib/lua-parser/pp.lua:237 -else -- ./lib/lua-parser/pp.lua:237 -str = str .. block2str(stm[4]) -- ./lib/lua-parser/pp.lua:239 -end -- ./lib/lua-parser/pp.lua:239 -str = str .. " }" -- ./lib/lua-parser/pp.lua:241 -elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } -- ./lib/lua-parser/pp.lua:242 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:243 -str = str .. varlist2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:244 -str = str .. explist2str(stm[2]) .. ", " -- ./lib/lua-parser/pp.lua:245 -str = str .. block2str(stm[3]) -- ./lib/lua-parser/pp.lua:246 -str = str .. " }" -- ./lib/lua-parser/pp.lua:247 -elseif tag == "Local" then -- `Local{ {ident+} {expr+}? } -- ./lib/lua-parser/pp.lua:248 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:249 -str = str .. varlist2str(stm[1]) -- ./lib/lua-parser/pp.lua:250 -if # stm[2] > 0 then -- ./lib/lua-parser/pp.lua:251 -str = str .. ", " .. explist2str(stm[2]) -- ./lib/lua-parser/pp.lua:252 -else -- ./lib/lua-parser/pp.lua:252 -str = str .. ", " .. "{ }" -- ./lib/lua-parser/pp.lua:254 -end -- ./lib/lua-parser/pp.lua:254 -str = str .. " }" -- ./lib/lua-parser/pp.lua:256 -elseif tag == "Localrec" then -- `Localrec{ ident expr } -- ./lib/lua-parser/pp.lua:257 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:258 -str = str .. "{ " .. var2str(stm[1][1]) .. " }, " -- ./lib/lua-parser/pp.lua:259 -str = str .. "{ " .. exp2str(stm[2][1]) .. " }" -- ./lib/lua-parser/pp.lua:260 -str = str .. " }" -- ./lib/lua-parser/pp.lua:261 -elseif tag == "Goto" or tag == "Label" then -- `Label{ } -- ./lib/lua-parser/pp.lua:263 -str = str .. "{ " .. name2str(stm[1]) .. " }" -- ./lib/lua-parser/pp.lua:264 -elseif tag == "Return" then -- `Return{ * } -- ./lib/lua-parser/pp.lua:265 -str = str .. explist2str(stm) -- ./lib/lua-parser/pp.lua:266 -elseif tag == "Break" then -- ./lib/lua-parser/pp.lua:267 - -- `Call{ expr expr* } -- ./lib/lua-parser/pp.lua:268 -elseif tag == "Call" then -- `Call{ expr expr* } -- ./lib/lua-parser/pp.lua:268 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:269 -str = str .. exp2str(stm[1]) -- ./lib/lua-parser/pp.lua:270 -if stm[2] then -- ./lib/lua-parser/pp.lua:271 -for i = 2, # stm do -- ./lib/lua-parser/pp.lua:272 -str = str .. ", " .. exp2str(stm[i]) -- ./lib/lua-parser/pp.lua:273 -end -- ./lib/lua-parser/pp.lua:273 -end -- ./lib/lua-parser/pp.lua:273 -str = str .. " }" -- ./lib/lua-parser/pp.lua:276 -elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } -- ./lib/lua-parser/pp.lua:277 -str = str .. "{ " -- ./lib/lua-parser/pp.lua:278 -str = str .. exp2str(stm[1]) .. ", " -- ./lib/lua-parser/pp.lua:279 -str = str .. exp2str(stm[2]) -- ./lib/lua-parser/pp.lua:280 -if stm[3] then -- ./lib/lua-parser/pp.lua:281 -for i = 3, # stm do -- ./lib/lua-parser/pp.lua:282 -str = str .. ", " .. exp2str(stm[i]) -- ./lib/lua-parser/pp.lua:283 -end -- ./lib/lua-parser/pp.lua:283 -end -- ./lib/lua-parser/pp.lua:283 -str = str .. " }" -- ./lib/lua-parser/pp.lua:286 -else -- ./lib/lua-parser/pp.lua:286 -error("expecting a statement, but got a " .. tag) -- ./lib/lua-parser/pp.lua:288 -end -- ./lib/lua-parser/pp.lua:288 -return str -- ./lib/lua-parser/pp.lua:290 -end -- ./lib/lua-parser/pp.lua:290 -block2str = function(block) -- ./lib/lua-parser/pp.lua:293 -local l = {} -- ./lib/lua-parser/pp.lua:294 -for k, v in ipairs(block) do -- ./lib/lua-parser/pp.lua:295 -l[k] = stm2str(v) -- ./lib/lua-parser/pp.lua:296 -end -- ./lib/lua-parser/pp.lua:296 -return "{ " .. table["concat"](l, ", ") .. " }" -- ./lib/lua-parser/pp.lua:298 -end -- ./lib/lua-parser/pp.lua:298 -pp["tostring"] = function(t) -- ./lib/lua-parser/pp.lua:301 -assert(type(t) == "table") -- ./lib/lua-parser/pp.lua:302 -return block2str(t) -- ./lib/lua-parser/pp.lua:303 -end -- ./lib/lua-parser/pp.lua:303 -pp["print"] = function(t) -- ./lib/lua-parser/pp.lua:306 -assert(type(t) == "table") -- ./lib/lua-parser/pp.lua:307 -print(pp["tostring"](t)) -- ./lib/lua-parser/pp.lua:308 -end -- ./lib/lua-parser/pp.lua:308 -pp["dump"] = function(t, i) -- ./lib/lua-parser/pp.lua:311 -if i == nil then -- ./lib/lua-parser/pp.lua:312 -i = 0 -- ./lib/lua-parser/pp.lua:312 -end -- ./lib/lua-parser/pp.lua:312 +]") do -- ./candran/can-parser/scope.lua:10 +l = l + 1 -- ./candran/can-parser/scope.lua:11 +lastline = line -- ./candran/can-parser/scope.lua:12 +end -- ./candran/can-parser/scope.lua:12 +local c = lastline:len() - 1 -- ./candran/can-parser/scope.lua:14 +return l, c ~= 0 and c or 1 -- ./candran/can-parser/scope.lua:15 +end -- ./candran/can-parser/scope.lua:15 +scope["new_scope"] = function(env) -- ./candran/can-parser/scope.lua:18 +if not env["scope"] then -- ./candran/can-parser/scope.lua:19 +env["scope"] = 0 -- ./candran/can-parser/scope.lua:20 +else -- ./candran/can-parser/scope.lua:20 +env["scope"] = env["scope"] + 1 -- ./candran/can-parser/scope.lua:22 +end -- ./candran/can-parser/scope.lua:22 +local scope = env["scope"] -- ./candran/can-parser/scope.lua:24 +env["maxscope"] = scope -- ./candran/can-parser/scope.lua:25 +env[scope] = {} -- ./candran/can-parser/scope.lua:26 +env[scope]["label"] = {} -- ./candran/can-parser/scope.lua:27 +env[scope]["local"] = {} -- ./candran/can-parser/scope.lua:28 +env[scope]["goto"] = {} -- ./candran/can-parser/scope.lua:29 +end -- ./candran/can-parser/scope.lua:29 +scope["begin_scope"] = function(env) -- ./candran/can-parser/scope.lua:32 +env["scope"] = env["scope"] + 1 -- ./candran/can-parser/scope.lua:33 +end -- ./candran/can-parser/scope.lua:33 +scope["end_scope"] = function(env) -- ./candran/can-parser/scope.lua:36 +env["scope"] = env["scope"] - 1 -- ./candran/can-parser/scope.lua:37 +end -- ./candran/can-parser/scope.lua:37 +scope["new_function"] = function(env) -- ./candran/can-parser/scope.lua:40 +if not env["fscope"] then -- ./candran/can-parser/scope.lua:41 +env["fscope"] = 0 -- ./candran/can-parser/scope.lua:42 +else -- ./candran/can-parser/scope.lua:42 +env["fscope"] = env["fscope"] + 1 -- ./candran/can-parser/scope.lua:44 +end -- ./candran/can-parser/scope.lua:44 +local fscope = env["fscope"] -- ./candran/can-parser/scope.lua:46 +env["function"][fscope] = {} -- ./candran/can-parser/scope.lua:47 +end -- ./candran/can-parser/scope.lua:47 +scope["begin_function"] = function(env) -- ./candran/can-parser/scope.lua:50 +env["fscope"] = env["fscope"] + 1 -- ./candran/can-parser/scope.lua:51 +end -- ./candran/can-parser/scope.lua:51 +scope["end_function"] = function(env) -- ./candran/can-parser/scope.lua:54 +env["fscope"] = env["fscope"] - 1 -- ./candran/can-parser/scope.lua:55 +end -- ./candran/can-parser/scope.lua:55 +scope["begin_loop"] = function(env) -- ./candran/can-parser/scope.lua:58 +if not env["loop"] then -- ./candran/can-parser/scope.lua:59 +env["loop"] = 1 -- ./candran/can-parser/scope.lua:60 +else -- ./candran/can-parser/scope.lua:60 +env["loop"] = env["loop"] + 1 -- ./candran/can-parser/scope.lua:62 +end -- ./candran/can-parser/scope.lua:62 +end -- ./candran/can-parser/scope.lua:62 +scope["end_loop"] = function(env) -- ./candran/can-parser/scope.lua:66 +env["loop"] = env["loop"] - 1 -- ./candran/can-parser/scope.lua:67 +end -- ./candran/can-parser/scope.lua:67 +scope["insideloop"] = function(env) -- ./candran/can-parser/scope.lua:70 +return env["loop"] and env["loop"] > 0 -- ./candran/can-parser/scope.lua:71 +end -- ./candran/can-parser/scope.lua:71 +return scope -- ./candran/can-parser/scope.lua:74 +end -- ./candran/can-parser/scope.lua:74 +local scope = _() or scope -- ./candran/can-parser/scope.lua:78 +package["loaded"]["candran.can-parser.scope"] = scope or true -- ./candran/can-parser/scope.lua:79 +local function _() -- ./candran/can-parser/scope.lua:82 +local scope = require("candran.can-parser.scope") -- ./candran/can-parser/validator.lua:4 +local lineno = scope["lineno"] -- ./candran/can-parser/validator.lua:6 +local new_scope, end_scope = scope["new_scope"], scope["end_scope"] -- ./candran/can-parser/validator.lua:7 +local new_function, end_function = scope["new_function"], scope["end_function"] -- ./candran/can-parser/validator.lua:8 +local begin_loop, end_loop = scope["begin_loop"], scope["end_loop"] -- ./candran/can-parser/validator.lua:9 +local insideloop = scope["insideloop"] -- ./candran/can-parser/validator.lua:10 +local function syntaxerror(errorinfo, pos, msg) -- ./candran/can-parser/validator.lua:13 +local l, c = lineno(errorinfo["subject"], pos) -- ./candran/can-parser/validator.lua:14 +local error_msg = "%s:%d:%d: syntax error, %s" -- ./candran/can-parser/validator.lua:15 +return string["format"](error_msg, errorinfo["filename"], l, c, msg) -- ./candran/can-parser/validator.lua:16 +end -- ./candran/can-parser/validator.lua:16 +local function exist_label(env, scope, stm) -- ./candran/can-parser/validator.lua:19 +local l = stm[1] -- ./candran/can-parser/validator.lua:20 +for s = scope, 0, - 1 do -- ./candran/can-parser/validator.lua:21 +if env[s]["label"][l] then -- ./candran/can-parser/validator.lua:22 +return true -- ./candran/can-parser/validator.lua:22 +end -- ./candran/can-parser/validator.lua:22 +end -- ./candran/can-parser/validator.lua:22 +return false -- ./candran/can-parser/validator.lua:24 +end -- ./candran/can-parser/validator.lua:24 +local function set_label(env, label, pos) -- ./candran/can-parser/validator.lua:27 +local scope = env["scope"] -- ./candran/can-parser/validator.lua:28 +local l = env[scope]["label"][label] -- ./candran/can-parser/validator.lua:29 +if not l then -- ./candran/can-parser/validator.lua:30 +env[scope]["label"][label] = { -- ./candran/can-parser/validator.lua:31 +["name"] = label, -- ./candran/can-parser/validator.lua:31 +["pos"] = pos -- ./candran/can-parser/validator.lua:31 +} -- ./candran/can-parser/validator.lua:31 +return true -- ./candran/can-parser/validator.lua:32 +else -- ./candran/can-parser/validator.lua:32 +local msg = "label '%s' already defined at line %d" -- ./candran/can-parser/validator.lua:34 +local line = lineno(env["errorinfo"]["subject"], l["pos"]) -- ./candran/can-parser/validator.lua:35 +msg = string["format"](msg, label, line) -- ./candran/can-parser/validator.lua:36 +return nil, syntaxerror(env["errorinfo"], pos, msg) -- ./candran/can-parser/validator.lua:37 +end -- ./candran/can-parser/validator.lua:37 +end -- ./candran/can-parser/validator.lua:37 +local function set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:41 +local scope = env["scope"] -- ./candran/can-parser/validator.lua:42 +table["insert"](env[scope]["goto"], stm) -- ./candran/can-parser/validator.lua:43 +return true -- ./candran/can-parser/validator.lua:44 +end -- ./candran/can-parser/validator.lua:44 +local function verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:47 +for s = env["maxscope"], 0, - 1 do -- ./candran/can-parser/validator.lua:48 +for k, v in ipairs(env[s]["goto"]) do -- ./candran/can-parser/validator.lua:49 +if not exist_label(env, s, v) then -- ./candran/can-parser/validator.lua:50 +local msg = "no visible label '%s' for " -- ./candran/can-parser/validator.lua:51 +msg = string["format"](msg, v[1]) -- ./candran/can-parser/validator.lua:52 +return nil, syntaxerror(env["errorinfo"], v["pos"], msg) -- ./candran/can-parser/validator.lua:53 +end -- ./candran/can-parser/validator.lua:53 +end -- ./candran/can-parser/validator.lua:53 +end -- ./candran/can-parser/validator.lua:53 +return true -- ./candran/can-parser/validator.lua:57 +end -- ./candran/can-parser/validator.lua:57 +local function set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:60 +env["function"][env["fscope"]]["is_vararg"] = is_vararg -- ./candran/can-parser/validator.lua:61 +end -- ./candran/can-parser/validator.lua:61 +local traverse_stm, traverse_exp, traverse_var -- ./candran/can-parser/validator.lua:64 +local traverse_block, traverse_explist, traverse_varlist, traverse_parlist -- ./candran/can-parser/validator.lua:65 +traverse_parlist = function(env, parlist) -- ./candran/can-parser/validator.lua:67 +local len = # parlist -- ./candran/can-parser/validator.lua:68 +local is_vararg = false -- ./candran/can-parser/validator.lua:69 +if len > 0 and parlist[len]["tag"] == "Dots" then -- ./candran/can-parser/validator.lua:70 +is_vararg = true -- ./candran/can-parser/validator.lua:71 +end -- ./candran/can-parser/validator.lua:71 +set_vararg(env, is_vararg) -- ./candran/can-parser/validator.lua:73 +return true -- ./candran/can-parser/validator.lua:74 +end -- ./candran/can-parser/validator.lua:74 +local function traverse_function(env, exp) -- ./candran/can-parser/validator.lua:77 +new_function(env) -- ./candran/can-parser/validator.lua:78 +new_scope(env) -- ./candran/can-parser/validator.lua:79 +local status, msg = traverse_parlist(env, exp[1]) -- ./candran/can-parser/validator.lua:80 +if not status then -- ./candran/can-parser/validator.lua:81 +return status, msg -- ./candran/can-parser/validator.lua:81 +end -- ./candran/can-parser/validator.lua:81 +status, msg = traverse_block(env, exp[2]) -- ./candran/can-parser/validator.lua:82 +if not status then -- ./candran/can-parser/validator.lua:83 +return status, msg -- ./candran/can-parser/validator.lua:83 +end -- ./candran/can-parser/validator.lua:83 +end_scope(env) -- ./candran/can-parser/validator.lua:84 +end_function(env) -- ./candran/can-parser/validator.lua:85 +return true -- ./candran/can-parser/validator.lua:86 +end -- ./candran/can-parser/validator.lua:86 +local function traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:89 +new_function(env) -- ./candran/can-parser/validator.lua:90 +new_scope(env) -- ./candran/can-parser/validator.lua:91 +local status, msg = traverse_block(env, exp[1]) -- ./candran/can-parser/validator.lua:92 +if not status then -- ./candran/can-parser/validator.lua:93 +return status, msg -- ./candran/can-parser/validator.lua:93 +end -- ./candran/can-parser/validator.lua:93 +end_scope(env) -- ./candran/can-parser/validator.lua:94 +end_function(env) -- ./candran/can-parser/validator.lua:95 +return true -- ./candran/can-parser/validator.lua:96 +end -- ./candran/can-parser/validator.lua:96 +local function traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:99 +new_function(env) -- ./candran/can-parser/validator.lua:100 +new_scope(env) -- ./candran/can-parser/validator.lua:101 +exp["tag"] = exp["tag"]:gsub("Expr$", "") -- ./candran/can-parser/validator.lua:102 +local status, msg = traverse_stm(env, exp) -- ./candran/can-parser/validator.lua:103 +exp["tag"] = exp["tag"] .. "Expr" -- ./candran/can-parser/validator.lua:104 +if not status then -- ./candran/can-parser/validator.lua:105 +return status, msg -- ./candran/can-parser/validator.lua:105 +end -- ./candran/can-parser/validator.lua:105 +end_scope(env) -- ./candran/can-parser/validator.lua:106 +end_function(env) -- ./candran/can-parser/validator.lua:107 +return true -- ./candran/can-parser/validator.lua:108 +end -- ./candran/can-parser/validator.lua:108 +local function traverse_op(env, exp) -- ./candran/can-parser/validator.lua:111 +local status, msg = traverse_exp(env, exp[2]) -- ./candran/can-parser/validator.lua:112 +if not status then -- ./candran/can-parser/validator.lua:113 +return status, msg -- ./candran/can-parser/validator.lua:113 +end -- ./candran/can-parser/validator.lua:113 +if exp[3] then -- ./candran/can-parser/validator.lua:114 +status, msg = traverse_exp(env, exp[3]) -- ./candran/can-parser/validator.lua:115 +if not status then -- ./candran/can-parser/validator.lua:116 +return status, msg -- ./candran/can-parser/validator.lua:116 +end -- ./candran/can-parser/validator.lua:116 +end -- ./candran/can-parser/validator.lua:116 +return true -- ./candran/can-parser/validator.lua:118 +end -- ./candran/can-parser/validator.lua:118 +local function traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:121 +local status, msg = traverse_exp(env, exp[1]) -- ./candran/can-parser/validator.lua:122 +if not status then -- ./candran/can-parser/validator.lua:123 +return status, msg -- ./candran/can-parser/validator.lua:123 +end -- ./candran/can-parser/validator.lua:123 +return true -- ./candran/can-parser/validator.lua:124 +end -- ./candran/can-parser/validator.lua:124 +local function traverse_table(env, fieldlist) -- ./candran/can-parser/validator.lua:127 +for k, v in ipairs(fieldlist) do -- ./candran/can-parser/validator.lua:128 +local tag = v["tag"] -- ./candran/can-parser/validator.lua:129 +if tag == "Pair" then -- ./candran/can-parser/validator.lua:130 +local status, msg = traverse_exp(env, v[1]) -- ./candran/can-parser/validator.lua:131 +if not status then -- ./candran/can-parser/validator.lua:132 +return status, msg -- ./candran/can-parser/validator.lua:132 +end -- ./candran/can-parser/validator.lua:132 +status, msg = traverse_exp(env, v[2]) -- ./candran/can-parser/validator.lua:133 +if not status then -- ./candran/can-parser/validator.lua:134 +return status, msg -- ./candran/can-parser/validator.lua:134 +end -- ./candran/can-parser/validator.lua:134 +else -- ./candran/can-parser/validator.lua:134 +local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:136 +if not status then -- ./candran/can-parser/validator.lua:137 +return status, msg -- ./candran/can-parser/validator.lua:137 +end -- ./candran/can-parser/validator.lua:137 +end -- ./candran/can-parser/validator.lua:137 +end -- ./candran/can-parser/validator.lua:137 +return true -- ./candran/can-parser/validator.lua:140 +end -- ./candran/can-parser/validator.lua:140 +local function traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:143 +if not env["function"][env["fscope"]]["is_vararg"] then -- ./candran/can-parser/validator.lua:144 +local msg = "cannot use '...' outside a vararg function" -- ./candran/can-parser/validator.lua:145 +return nil, syntaxerror(env["errorinfo"], exp["pos"], msg) -- ./candran/can-parser/validator.lua:146 +end -- ./candran/can-parser/validator.lua:146 +return true -- ./candran/can-parser/validator.lua:148 +end -- ./candran/can-parser/validator.lua:148 +local function traverse_call(env, call) -- ./candran/can-parser/validator.lua:151 +local status, msg = traverse_exp(env, call[1]) -- ./candran/can-parser/validator.lua:152 +if not status then -- ./candran/can-parser/validator.lua:153 +return status, msg -- ./candran/can-parser/validator.lua:153 +end -- ./candran/can-parser/validator.lua:153 +for i = 2, # call do -- ./candran/can-parser/validator.lua:154 +status, msg = traverse_exp(env, call[i]) -- ./candran/can-parser/validator.lua:155 +if not status then -- ./candran/can-parser/validator.lua:156 +return status, msg -- ./candran/can-parser/validator.lua:156 +end -- ./candran/can-parser/validator.lua:156 +end -- ./candran/can-parser/validator.lua:156 +return true -- ./candran/can-parser/validator.lua:158 +end -- ./candran/can-parser/validator.lua:158 +local function traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:161 +local status, msg = traverse_varlist(env, stm[1]) -- ./candran/can-parser/validator.lua:162 +if not status then -- ./candran/can-parser/validator.lua:163 +return status, msg -- ./candran/can-parser/validator.lua:163 +end -- ./candran/can-parser/validator.lua:163 +status, msg = traverse_explist(env, stm[# stm]) -- ./candran/can-parser/validator.lua:164 +if not status then -- ./candran/can-parser/validator.lua:165 +return status, msg -- ./candran/can-parser/validator.lua:165 +end -- ./candran/can-parser/validator.lua:165 +return true -- ./candran/can-parser/validator.lua:166 +end -- ./candran/can-parser/validator.lua:166 +local function traverse_break(env, stm) -- ./candran/can-parser/validator.lua:169 +if not insideloop(env) then -- ./candran/can-parser/validator.lua:170 +local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:171 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:172 +end -- ./candran/can-parser/validator.lua:172 +return true -- ./candran/can-parser/validator.lua:174 +end -- ./candran/can-parser/validator.lua:174 +local function traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:177 +if not insideloop(env) then -- ./candran/can-parser/validator.lua:178 +local msg = " not inside a loop" -- ./candran/can-parser/validator.lua:179 +return nil, syntaxerror(env["errorinfo"], stm["pos"], msg) -- ./candran/can-parser/validator.lua:180 +end -- ./candran/can-parser/validator.lua:180 +return true -- ./candran/can-parser/validator.lua:182 +end -- ./candran/can-parser/validator.lua:182 +local function traverse_push(env, stm) -- ./candran/can-parser/validator.lua:185 +local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:186 +if not status then -- ./candran/can-parser/validator.lua:187 +return status, msg -- ./candran/can-parser/validator.lua:187 +end -- ./candran/can-parser/validator.lua:187 +return true -- ./candran/can-parser/validator.lua:188 +end -- ./candran/can-parser/validator.lua:188 +local function traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:191 +begin_loop(env) -- ./candran/can-parser/validator.lua:192 +new_scope(env) -- ./candran/can-parser/validator.lua:193 +local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:194 +if not status then -- ./candran/can-parser/validator.lua:195 +return status, msg -- ./candran/can-parser/validator.lua:195 +end -- ./candran/can-parser/validator.lua:195 +status, msg = traverse_block(env, stm[3]) -- ./candran/can-parser/validator.lua:196 +if not status then -- ./candran/can-parser/validator.lua:197 +return status, msg -- ./candran/can-parser/validator.lua:197 +end -- ./candran/can-parser/validator.lua:197 +end_scope(env) -- ./candran/can-parser/validator.lua:198 +end_loop(env) -- ./candran/can-parser/validator.lua:199 +return true -- ./candran/can-parser/validator.lua:200 +end -- ./candran/can-parser/validator.lua:200 +local function traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:203 +local status, msg -- ./candran/can-parser/validator.lua:204 +begin_loop(env) -- ./candran/can-parser/validator.lua:205 +new_scope(env) -- ./candran/can-parser/validator.lua:206 +status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:207 +if not status then -- ./candran/can-parser/validator.lua:208 +return status, msg -- ./candran/can-parser/validator.lua:208 +end -- ./candran/can-parser/validator.lua:208 +status, msg = traverse_exp(env, stm[3]) -- ./candran/can-parser/validator.lua:209 +if not status then -- ./candran/can-parser/validator.lua:210 +return status, msg -- ./candran/can-parser/validator.lua:210 +end -- ./candran/can-parser/validator.lua:210 +if stm[5] then -- ./candran/can-parser/validator.lua:211 +status, msg = traverse_exp(env, stm[4]) -- ./candran/can-parser/validator.lua:212 +if not status then -- ./candran/can-parser/validator.lua:213 +return status, msg -- ./candran/can-parser/validator.lua:213 +end -- ./candran/can-parser/validator.lua:213 +status, msg = traverse_block(env, stm[5]) -- ./candran/can-parser/validator.lua:214 +if not status then -- ./candran/can-parser/validator.lua:215 +return status, msg -- ./candran/can-parser/validator.lua:215 +end -- ./candran/can-parser/validator.lua:215 +else -- ./candran/can-parser/validator.lua:215 +status, msg = traverse_block(env, stm[4]) -- ./candran/can-parser/validator.lua:217 +if not status then -- ./candran/can-parser/validator.lua:218 +return status, msg -- ./candran/can-parser/validator.lua:218 +end -- ./candran/can-parser/validator.lua:218 +end -- ./candran/can-parser/validator.lua:218 +end_scope(env) -- ./candran/can-parser/validator.lua:220 +end_loop(env) -- ./candran/can-parser/validator.lua:221 +return true -- ./candran/can-parser/validator.lua:222 +end -- ./candran/can-parser/validator.lua:222 +local function traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:225 +local status, msg = set_pending_goto(env, stm) -- ./candran/can-parser/validator.lua:226 +if not status then -- ./candran/can-parser/validator.lua:227 +return status, msg -- ./candran/can-parser/validator.lua:227 +end -- ./candran/can-parser/validator.lua:227 +return true -- ./candran/can-parser/validator.lua:228 +end -- ./candran/can-parser/validator.lua:228 +local function traverse_let(env, stm) -- ./candran/can-parser/validator.lua:231 +local status, msg = traverse_explist(env, stm[2]) -- ./candran/can-parser/validator.lua:232 +if not status then -- ./candran/can-parser/validator.lua:233 +return status, msg -- ./candran/can-parser/validator.lua:233 +end -- ./candran/can-parser/validator.lua:233 +return true -- ./candran/can-parser/validator.lua:234 +end -- ./candran/can-parser/validator.lua:234 +local function traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:237 +local status, msg = traverse_exp(env, stm[2][1]) -- ./candran/can-parser/validator.lua:238 +if not status then -- ./candran/can-parser/validator.lua:239 +return status, msg -- ./candran/can-parser/validator.lua:239 +end -- ./candran/can-parser/validator.lua:239 +return true -- ./candran/can-parser/validator.lua:240 +end -- ./candran/can-parser/validator.lua:240 +local function traverse_if(env, stm) -- ./candran/can-parser/validator.lua:243 +local len = # stm -- ./candran/can-parser/validator.lua:244 +if len % 2 == 0 then -- ./candran/can-parser/validator.lua:245 +for i = 1, len, 2 do -- ./candran/can-parser/validator.lua:246 +local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:247 +if not status then -- ./candran/can-parser/validator.lua:248 +return status, msg -- ./candran/can-parser/validator.lua:248 +end -- ./candran/can-parser/validator.lua:248 +status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:249 +if not status then -- ./candran/can-parser/validator.lua:250 +return status, msg -- ./candran/can-parser/validator.lua:250 +end -- ./candran/can-parser/validator.lua:250 +end -- ./candran/can-parser/validator.lua:250 +else -- ./candran/can-parser/validator.lua:250 +for i = 1, len - 1, 2 do -- ./candran/can-parser/validator.lua:253 +local status, msg = traverse_exp(env, stm[i]) -- ./candran/can-parser/validator.lua:254 +if not status then -- ./candran/can-parser/validator.lua:255 +return status, msg -- ./candran/can-parser/validator.lua:255 +end -- ./candran/can-parser/validator.lua:255 +status, msg = traverse_block(env, stm[i + 1]) -- ./candran/can-parser/validator.lua:256 +if not status then -- ./candran/can-parser/validator.lua:257 +return status, msg -- ./candran/can-parser/validator.lua:257 +end -- ./candran/can-parser/validator.lua:257 +end -- ./candran/can-parser/validator.lua:257 +local status, msg = traverse_block(env, stm[len]) -- ./candran/can-parser/validator.lua:259 +if not status then -- ./candran/can-parser/validator.lua:260 +return status, msg -- ./candran/can-parser/validator.lua:260 +end -- ./candran/can-parser/validator.lua:260 +end -- ./candran/can-parser/validator.lua:260 +return true -- ./candran/can-parser/validator.lua:262 +end -- ./candran/can-parser/validator.lua:262 +local function traverse_label(env, stm) -- ./candran/can-parser/validator.lua:265 +local status, msg = set_label(env, stm[1], stm["pos"]) -- ./candran/can-parser/validator.lua:266 +if not status then -- ./candran/can-parser/validator.lua:267 +return status, msg -- ./candran/can-parser/validator.lua:267 +end -- ./candran/can-parser/validator.lua:267 +return true -- ./candran/can-parser/validator.lua:268 +end -- ./candran/can-parser/validator.lua:268 +local function traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:271 +begin_loop(env) -- ./candran/can-parser/validator.lua:272 +local status, msg = traverse_block(env, stm[1]) -- ./candran/can-parser/validator.lua:273 +if not status then -- ./candran/can-parser/validator.lua:274 +return status, msg -- ./candran/can-parser/validator.lua:274 +end -- ./candran/can-parser/validator.lua:274 +status, msg = traverse_exp(env, stm[2]) -- ./candran/can-parser/validator.lua:275 +if not status then -- ./candran/can-parser/validator.lua:276 +return status, msg -- ./candran/can-parser/validator.lua:276 +end -- ./candran/can-parser/validator.lua:276 +end_loop(env) -- ./candran/can-parser/validator.lua:277 +return true -- ./candran/can-parser/validator.lua:278 +end -- ./candran/can-parser/validator.lua:278 +local function traverse_return(env, stm) -- ./candran/can-parser/validator.lua:281 +local status, msg = traverse_explist(env, stm) -- ./candran/can-parser/validator.lua:282 +if not status then -- ./candran/can-parser/validator.lua:283 +return status, msg -- ./candran/can-parser/validator.lua:283 +end -- ./candran/can-parser/validator.lua:283 +return true -- ./candran/can-parser/validator.lua:284 +end -- ./candran/can-parser/validator.lua:284 +local function traverse_while(env, stm) -- ./candran/can-parser/validator.lua:287 +begin_loop(env) -- ./candran/can-parser/validator.lua:288 +local status, msg = traverse_exp(env, stm[1]) -- ./candran/can-parser/validator.lua:289 +if not status then -- ./candran/can-parser/validator.lua:290 +return status, msg -- ./candran/can-parser/validator.lua:290 +end -- ./candran/can-parser/validator.lua:290 +status, msg = traverse_block(env, stm[2]) -- ./candran/can-parser/validator.lua:291 +if not status then -- ./candran/can-parser/validator.lua:292 +return status, msg -- ./candran/can-parser/validator.lua:292 +end -- ./candran/can-parser/validator.lua:292 +end_loop(env) -- ./candran/can-parser/validator.lua:293 +return true -- ./candran/can-parser/validator.lua:294 +end -- ./candran/can-parser/validator.lua:294 +traverse_var = function(env, var) -- ./candran/can-parser/validator.lua:297 +local tag = var["tag"] -- ./candran/can-parser/validator.lua:298 +if tag == "Id" then -- ./candran/can-parser/validator.lua:299 +return true -- ./candran/can-parser/validator.lua:300 +elseif tag == "Index" then -- ./candran/can-parser/validator.lua:301 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:302 +if not status then -- ./candran/can-parser/validator.lua:303 +return status, msg -- ./candran/can-parser/validator.lua:303 +end -- ./candran/can-parser/validator.lua:303 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:304 +if not status then -- ./candran/can-parser/validator.lua:305 +return status, msg -- ./candran/can-parser/validator.lua:305 +end -- ./candran/can-parser/validator.lua:305 +return true -- ./candran/can-parser/validator.lua:306 +elseif tag == "DestructuringId" then -- ./candran/can-parser/validator.lua:307 +return traverse_table(env, var) -- ./candran/can-parser/validator.lua:308 +else -- ./candran/can-parser/validator.lua:308 +error("expecting a variable, but got a " .. tag) -- ./candran/can-parser/validator.lua:310 +end -- ./candran/can-parser/validator.lua:310 +end -- ./candran/can-parser/validator.lua:310 +traverse_varlist = function(env, varlist) -- ./candran/can-parser/validator.lua:314 +for k, v in ipairs(varlist) do -- ./candran/can-parser/validator.lua:315 +local status, msg = traverse_var(env, v) -- ./candran/can-parser/validator.lua:316 +if not status then -- ./candran/can-parser/validator.lua:317 +return status, msg -- ./candran/can-parser/validator.lua:317 +end -- ./candran/can-parser/validator.lua:317 +end -- ./candran/can-parser/validator.lua:317 +return true -- ./candran/can-parser/validator.lua:319 +end -- ./candran/can-parser/validator.lua:319 +local function traverse_methodstub(env, var) -- ./candran/can-parser/validator.lua:322 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:323 +if not status then -- ./candran/can-parser/validator.lua:324 +return status, msg -- ./candran/can-parser/validator.lua:324 +end -- ./candran/can-parser/validator.lua:324 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:325 +if not status then -- ./candran/can-parser/validator.lua:326 +return status, msg -- ./candran/can-parser/validator.lua:326 +end -- ./candran/can-parser/validator.lua:326 +return true -- ./candran/can-parser/validator.lua:327 +end -- ./candran/can-parser/validator.lua:327 +local function traverse_safeindex(env, var) -- ./candran/can-parser/validator.lua:330 +local status, msg = traverse_exp(env, var[1]) -- ./candran/can-parser/validator.lua:331 +if not status then -- ./candran/can-parser/validator.lua:332 +return status, msg -- ./candran/can-parser/validator.lua:332 +end -- ./candran/can-parser/validator.lua:332 +status, msg = traverse_exp(env, var[2]) -- ./candran/can-parser/validator.lua:333 +if not status then -- ./candran/can-parser/validator.lua:334 +return status, msg -- ./candran/can-parser/validator.lua:334 +end -- ./candran/can-parser/validator.lua:334 +return true -- ./candran/can-parser/validator.lua:335 +end -- ./candran/can-parser/validator.lua:335 +traverse_exp = function(env, exp) -- ./candran/can-parser/validator.lua:338 +local tag = exp["tag"] -- ./candran/can-parser/validator.lua:339 +if tag == "Nil" or tag == "Boolean" or tag == "Number" or tag == "String" then -- ./candran/can-parser/validator.lua:343 +return true -- ./candran/can-parser/validator.lua:344 +elseif tag == "Dots" then -- ./candran/can-parser/validator.lua:345 +return traverse_vararg(env, exp) -- ./candran/can-parser/validator.lua:346 +elseif tag == "Function" then -- ./candran/can-parser/validator.lua:347 +return traverse_function(env, exp) -- ./candran/can-parser/validator.lua:348 +elseif tag == "Table" then -- ./candran/can-parser/validator.lua:349 +return traverse_table(env, exp) -- ./candran/can-parser/validator.lua:350 +elseif tag == "Op" then -- ./candran/can-parser/validator.lua:351 +return traverse_op(env, exp) -- ./candran/can-parser/validator.lua:352 +elseif tag == "Paren" then -- ./candran/can-parser/validator.lua:353 +return traverse_paren(env, exp) -- ./candran/can-parser/validator.lua:354 +elseif tag == "Call" or tag == "SafeCall" then -- ./candran/can-parser/validator.lua:355 +return traverse_call(env, exp) -- ./candran/can-parser/validator.lua:356 +elseif tag == "Id" or tag == "Index" then -- ./candran/can-parser/validator.lua:358 +return traverse_var(env, exp) -- ./candran/can-parser/validator.lua:359 +elseif tag == "SafeIndex" then -- ./candran/can-parser/validator.lua:360 +return traverse_safeindex(env, exp) -- ./candran/can-parser/validator.lua:361 +elseif tag == "TableCompr" then -- ./candran/can-parser/validator.lua:362 +return traverse_tablecompr(env, exp) -- ./candran/can-parser/validator.lua:363 +elseif tag == "MethodStub" or tag == "SafeMethodStub" then -- ./candran/can-parser/validator.lua:364 +return traverse_methodstub(env, exp) -- ./candran/can-parser/validator.lua:365 +elseif tag:match("Expr$") then -- ./candran/can-parser/validator.lua:366 +return traverse_statexpr(env, exp) -- ./candran/can-parser/validator.lua:367 +else -- ./candran/can-parser/validator.lua:367 +error("expecting an expression, but got a " .. tag) -- ./candran/can-parser/validator.lua:369 +end -- ./candran/can-parser/validator.lua:369 +end -- ./candran/can-parser/validator.lua:369 +traverse_explist = function(env, explist) -- ./candran/can-parser/validator.lua:373 +for k, v in ipairs(explist) do -- ./candran/can-parser/validator.lua:374 +local status, msg = traverse_exp(env, v) -- ./candran/can-parser/validator.lua:375 +if not status then -- ./candran/can-parser/validator.lua:376 +return status, msg -- ./candran/can-parser/validator.lua:376 +end -- ./candran/can-parser/validator.lua:376 +end -- ./candran/can-parser/validator.lua:376 +return true -- ./candran/can-parser/validator.lua:378 +end -- ./candran/can-parser/validator.lua:378 +traverse_stm = function(env, stm) -- ./candran/can-parser/validator.lua:381 +local tag = stm["tag"] -- ./candran/can-parser/validator.lua:382 +if tag == "Do" then -- ./candran/can-parser/validator.lua:383 +return traverse_block(env, stm) -- ./candran/can-parser/validator.lua:384 +elseif tag == "Set" then -- ./candran/can-parser/validator.lua:385 +return traverse_assignment(env, stm) -- ./candran/can-parser/validator.lua:386 +elseif tag == "While" then -- ./candran/can-parser/validator.lua:387 +return traverse_while(env, stm) -- ./candran/can-parser/validator.lua:388 +elseif tag == "Repeat" then -- ./candran/can-parser/validator.lua:389 +return traverse_repeat(env, stm) -- ./candran/can-parser/validator.lua:390 +elseif tag == "If" then -- ./candran/can-parser/validator.lua:391 +return traverse_if(env, stm) -- ./candran/can-parser/validator.lua:392 +elseif tag == "Fornum" then -- ./candran/can-parser/validator.lua:393 +return traverse_fornum(env, stm) -- ./candran/can-parser/validator.lua:394 +elseif tag == "Forin" then -- ./candran/can-parser/validator.lua:395 +return traverse_forin(env, stm) -- ./candran/can-parser/validator.lua:396 +elseif tag == "Local" or tag == "Let" then -- ./candran/can-parser/validator.lua:398 +return traverse_let(env, stm) -- ./candran/can-parser/validator.lua:399 +elseif tag == "Localrec" then -- ./candran/can-parser/validator.lua:400 +return traverse_letrec(env, stm) -- ./candran/can-parser/validator.lua:401 +elseif tag == "Goto" then -- ./candran/can-parser/validator.lua:402 +return traverse_goto(env, stm) -- ./candran/can-parser/validator.lua:403 +elseif tag == "Label" then -- ./candran/can-parser/validator.lua:404 +return traverse_label(env, stm) -- ./candran/can-parser/validator.lua:405 +elseif tag == "Return" then -- ./candran/can-parser/validator.lua:406 +return traverse_return(env, stm) -- ./candran/can-parser/validator.lua:407 +elseif tag == "Break" then -- ./candran/can-parser/validator.lua:408 +return traverse_break(env, stm) -- ./candran/can-parser/validator.lua:409 +elseif tag == "Call" then -- ./candran/can-parser/validator.lua:410 +return traverse_call(env, stm) -- ./candran/can-parser/validator.lua:411 +elseif tag == "Continue" then -- ./candran/can-parser/validator.lua:412 +return traverse_continue(env, stm) -- ./candran/can-parser/validator.lua:413 +elseif tag == "Push" then -- ./candran/can-parser/validator.lua:414 +return traverse_push(env, stm) -- ./candran/can-parser/validator.lua:415 +else -- ./candran/can-parser/validator.lua:415 +error("expecting a statement, but got a " .. tag) -- ./candran/can-parser/validator.lua:417 +end -- ./candran/can-parser/validator.lua:417 +end -- ./candran/can-parser/validator.lua:417 +traverse_block = function(env, block) -- ./candran/can-parser/validator.lua:421 +local l = {} -- ./candran/can-parser/validator.lua:422 +new_scope(env) -- ./candran/can-parser/validator.lua:423 +for k, v in ipairs(block) do -- ./candran/can-parser/validator.lua:424 +local status, msg = traverse_stm(env, v) -- ./candran/can-parser/validator.lua:425 +if not status then -- ./candran/can-parser/validator.lua:426 +return status, msg -- ./candran/can-parser/validator.lua:426 +end -- ./candran/can-parser/validator.lua:426 +end -- ./candran/can-parser/validator.lua:426 +end_scope(env) -- ./candran/can-parser/validator.lua:428 +return true -- ./candran/can-parser/validator.lua:429 +end -- ./candran/can-parser/validator.lua:429 +local function traverse(ast, errorinfo) -- ./candran/can-parser/validator.lua:433 +assert(type(ast) == "table") -- ./candran/can-parser/validator.lua:434 +assert(type(errorinfo) == "table") -- ./candran/can-parser/validator.lua:435 +local env = { -- ./candran/can-parser/validator.lua:436 +["errorinfo"] = errorinfo, -- ./candran/can-parser/validator.lua:436 +["function"] = {} -- ./candran/can-parser/validator.lua:436 +} -- ./candran/can-parser/validator.lua:436 +new_function(env) -- ./candran/can-parser/validator.lua:437 +set_vararg(env, true) -- ./candran/can-parser/validator.lua:438 +local status, msg = traverse_block(env, ast) -- ./candran/can-parser/validator.lua:439 +if not status then -- ./candran/can-parser/validator.lua:440 +return status, msg -- ./candran/can-parser/validator.lua:440 +end -- ./candran/can-parser/validator.lua:440 +end_function(env) -- ./candran/can-parser/validator.lua:441 +status, msg = verify_pending_gotos(env) -- ./candran/can-parser/validator.lua:442 +if not status then -- ./candran/can-parser/validator.lua:443 +return status, msg -- ./candran/can-parser/validator.lua:443 +end -- ./candran/can-parser/validator.lua:443 +return ast -- ./candran/can-parser/validator.lua:444 +end -- ./candran/can-parser/validator.lua:444 +return { -- ./candran/can-parser/validator.lua:447 +["validate"] = traverse, -- ./candran/can-parser/validator.lua:447 +["syntaxerror"] = syntaxerror -- ./candran/can-parser/validator.lua:447 +} -- ./candran/can-parser/validator.lua:447 +end -- ./candran/can-parser/validator.lua:447 +local validator = _() or validator -- ./candran/can-parser/validator.lua:451 +package["loaded"]["candran.can-parser.validator"] = validator or true -- ./candran/can-parser/validator.lua:452 +local function _() -- ./candran/can-parser/validator.lua:455 +local pp = {} -- ./candran/can-parser/pp.lua:4 +local block2str, stm2str, exp2str, var2str -- ./candran/can-parser/pp.lua:6 +local explist2str, varlist2str, parlist2str, fieldlist2str -- ./candran/can-parser/pp.lua:7 +local function iscntrl(x) -- ./candran/can-parser/pp.lua:9 +if (x >= 0 and x <= 31) or (x == 127) then -- ./candran/can-parser/pp.lua:10 +return true -- ./candran/can-parser/pp.lua:10 +end -- ./candran/can-parser/pp.lua:10 +return false -- ./candran/can-parser/pp.lua:11 +end -- ./candran/can-parser/pp.lua:11 +local function isprint(x) -- ./candran/can-parser/pp.lua:14 +return not iscntrl(x) -- ./candran/can-parser/pp.lua:15 +end -- ./candran/can-parser/pp.lua:15 +local function fixed_string(str) -- ./candran/can-parser/pp.lua:18 +local new_str = "" -- ./candran/can-parser/pp.lua:19 +for i = 1, string["len"](str) do -- ./candran/can-parser/pp.lua:20 +char = string["byte"](str, i) -- ./candran/can-parser/pp.lua:21 +if char == 34 then -- ./candran/can-parser/pp.lua:22 +new_str = new_str .. string["format"]("\\\"") -- ./candran/can-parser/pp.lua:22 +elseif char == 92 then -- ./candran/can-parser/pp.lua:23 +new_str = new_str .. string["format"]("\\\\") -- ./candran/can-parser/pp.lua:23 +elseif char == 7 then -- ./candran/can-parser/pp.lua:24 +new_str = new_str .. string["format"]("\\a") -- ./candran/can-parser/pp.lua:24 +elseif char == 8 then -- ./candran/can-parser/pp.lua:25 +new_str = new_str .. string["format"]("\\b") -- ./candran/can-parser/pp.lua:25 +elseif char == 12 then -- ./candran/can-parser/pp.lua:26 +new_str = new_str .. string["format"]("\\f") -- ./candran/can-parser/pp.lua:26 +elseif char == 10 then -- ./candran/can-parser/pp.lua:27 +new_str = new_str .. string["format"]("\\n") -- ./candran/can-parser/pp.lua:27 +elseif char == 13 then -- ./candran/can-parser/pp.lua:28 +new_str = new_str .. string["format"]("\\r") -- ./candran/can-parser/pp.lua:28 +elseif char == 9 then -- ./candran/can-parser/pp.lua:29 +new_str = new_str .. string["format"]("\\t") -- ./candran/can-parser/pp.lua:29 +elseif char == 11 then -- ./candran/can-parser/pp.lua:30 +new_str = new_str .. string["format"]("\\v") -- ./candran/can-parser/pp.lua:30 +else -- ./candran/can-parser/pp.lua:30 +if isprint(char) then -- ./candran/can-parser/pp.lua:32 +new_str = new_str .. string["format"]("%c", char) -- ./candran/can-parser/pp.lua:33 +else -- ./candran/can-parser/pp.lua:33 +new_str = new_str .. string["format"]("\\%03d", char) -- ./candran/can-parser/pp.lua:35 +end -- ./candran/can-parser/pp.lua:35 +end -- ./candran/can-parser/pp.lua:35 +end -- ./candran/can-parser/pp.lua:35 +return new_str -- ./candran/can-parser/pp.lua:39 +end -- ./candran/can-parser/pp.lua:39 +local function name2str(name) -- ./candran/can-parser/pp.lua:42 +return string["format"]("\"%s\"", name) -- ./candran/can-parser/pp.lua:43 +end -- ./candran/can-parser/pp.lua:43 +local function boolean2str(b) -- ./candran/can-parser/pp.lua:46 +return string["format"]("\"%s\"", tostring(b)) -- ./candran/can-parser/pp.lua:47 +end -- ./candran/can-parser/pp.lua:47 +local function number2str(n) -- ./candran/can-parser/pp.lua:50 +return string["format"]("\"%s\"", tostring(n)) -- ./candran/can-parser/pp.lua:51 +end -- ./candran/can-parser/pp.lua:51 +local function string2str(s) -- ./candran/can-parser/pp.lua:54 +return string["format"]("\"%s\"", fixed_string(s)) -- ./candran/can-parser/pp.lua:55 +end -- ./candran/can-parser/pp.lua:55 +var2str = function(var) -- ./candran/can-parser/pp.lua:58 +local tag = var["tag"] -- ./candran/can-parser/pp.lua:59 +local str = "`" .. tag -- ./candran/can-parser/pp.lua:60 +if tag == "Id" then -- ./candran/can-parser/pp.lua:61 +str = str .. " " .. name2str(var[1]) -- ./candran/can-parser/pp.lua:62 +elseif tag == "Index" then -- ./candran/can-parser/pp.lua:63 +str = str .. "{ " -- ./candran/can-parser/pp.lua:64 +str = str .. exp2str(var[1]) .. ", " -- ./candran/can-parser/pp.lua:65 +str = str .. exp2str(var[2]) -- ./candran/can-parser/pp.lua:66 +str = str .. " }" -- ./candran/can-parser/pp.lua:67 +else -- ./candran/can-parser/pp.lua:67 +error("expecting a variable, but got a " .. tag) -- ./candran/can-parser/pp.lua:69 +end -- ./candran/can-parser/pp.lua:69 +return str -- ./candran/can-parser/pp.lua:71 +end -- ./candran/can-parser/pp.lua:71 +varlist2str = function(varlist) -- ./candran/can-parser/pp.lua:74 +local l = {} -- ./candran/can-parser/pp.lua:75 +for k, v in ipairs(varlist) do -- ./candran/can-parser/pp.lua:76 +l[k] = var2str(v) -- ./candran/can-parser/pp.lua:77 +end -- ./candran/can-parser/pp.lua:77 +return "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:79 +end -- ./candran/can-parser/pp.lua:79 +parlist2str = function(parlist) -- ./candran/can-parser/pp.lua:82 +local l = {} -- ./candran/can-parser/pp.lua:83 +local len = # parlist -- ./candran/can-parser/pp.lua:84 +local is_vararg = false -- ./candran/can-parser/pp.lua:85 +if len > 0 and parlist[len]["tag"] == "Dots" then -- ./candran/can-parser/pp.lua:86 +is_vararg = true -- ./candran/can-parser/pp.lua:87 +len = len - 1 -- ./candran/can-parser/pp.lua:88 +end -- ./candran/can-parser/pp.lua:88 +local i = 1 -- ./candran/can-parser/pp.lua:90 +while i <= len do -- ./candran/can-parser/pp.lua:91 +l[i] = var2str(parlist[i]) -- ./candran/can-parser/pp.lua:92 +i = i + 1 -- ./candran/can-parser/pp.lua:93 +end -- ./candran/can-parser/pp.lua:93 +if is_vararg then -- ./candran/can-parser/pp.lua:95 +l[i] = "`" .. parlist[i]["tag"] -- ./candran/can-parser/pp.lua:96 +end -- ./candran/can-parser/pp.lua:96 +return "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:98 +end -- ./candran/can-parser/pp.lua:98 +fieldlist2str = function(fieldlist) -- ./candran/can-parser/pp.lua:101 +local l = {} -- ./candran/can-parser/pp.lua:102 +for k, v in ipairs(fieldlist) do -- ./candran/can-parser/pp.lua:103 +local tag = v["tag"] -- ./candran/can-parser/pp.lua:104 +if tag == "Pair" then -- ./candran/can-parser/pp.lua:105 +l[k] = "`" .. tag .. "{ " -- ./candran/can-parser/pp.lua:106 +l[k] = l[k] .. exp2str(v[1]) .. ", " .. exp2str(v[2]) -- ./candran/can-parser/pp.lua:107 +l[k] = l[k] .. " }" -- ./candran/can-parser/pp.lua:108 +else -- ./candran/can-parser/pp.lua:108 +l[k] = exp2str(v) -- ./candran/can-parser/pp.lua:110 +end -- ./candran/can-parser/pp.lua:110 +end -- ./candran/can-parser/pp.lua:110 +if # l > 0 then -- ./candran/can-parser/pp.lua:113 +return "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:114 +else -- ./candran/can-parser/pp.lua:114 +return "" -- ./candran/can-parser/pp.lua:116 +end -- ./candran/can-parser/pp.lua:116 +end -- ./candran/can-parser/pp.lua:116 +exp2str = function(exp) -- ./candran/can-parser/pp.lua:120 +local tag = exp["tag"] -- ./candran/can-parser/pp.lua:121 +local str = "`" .. tag -- ./candran/can-parser/pp.lua:122 +if tag == "Nil" or tag == "Dots" then -- ./candran/can-parser/pp.lua:124 + -- ./candran/can-parser/pp.lua:125 +elseif tag == "Boolean" then -- ./candran/can-parser/pp.lua:125 +str = str .. " " .. boolean2str(exp[1]) -- ./candran/can-parser/pp.lua:126 +elseif tag == "Number" then -- ./candran/can-parser/pp.lua:127 +str = str .. " " .. number2str(exp[1]) -- ./candran/can-parser/pp.lua:128 +elseif tag == "String" then -- ./candran/can-parser/pp.lua:129 +str = str .. " " .. string2str(exp[1]) -- ./candran/can-parser/pp.lua:130 +elseif tag == "Function" then -- ./candran/can-parser/pp.lua:131 +str = str .. "{ " -- ./candran/can-parser/pp.lua:132 +str = str .. parlist2str(exp[1]) .. ", " -- ./candran/can-parser/pp.lua:133 +str = str .. block2str(exp[2]) -- ./candran/can-parser/pp.lua:134 +str = str .. " }" -- ./candran/can-parser/pp.lua:135 +elseif tag == "Table" then -- ./candran/can-parser/pp.lua:136 +str = str .. fieldlist2str(exp) -- ./candran/can-parser/pp.lua:137 +elseif tag == "Op" then -- ./candran/can-parser/pp.lua:138 +str = str .. "{ " -- ./candran/can-parser/pp.lua:139 +str = str .. name2str(exp[1]) .. ", " -- ./candran/can-parser/pp.lua:140 +str = str .. exp2str(exp[2]) -- ./candran/can-parser/pp.lua:141 +if exp[3] then -- ./candran/can-parser/pp.lua:142 +str = str .. ", " .. exp2str(exp[3]) -- ./candran/can-parser/pp.lua:143 +end -- ./candran/can-parser/pp.lua:143 +str = str .. " }" -- ./candran/can-parser/pp.lua:145 +elseif tag == "Paren" then -- ./candran/can-parser/pp.lua:146 +str = str .. "{ " .. exp2str(exp[1]) .. " }" -- ./candran/can-parser/pp.lua:147 +elseif tag == "Call" then -- ./candran/can-parser/pp.lua:148 +str = str .. "{ " -- ./candran/can-parser/pp.lua:149 +str = str .. exp2str(exp[1]) -- ./candran/can-parser/pp.lua:150 +if exp[2] then -- ./candran/can-parser/pp.lua:151 +for i = 2, # exp do -- ./candran/can-parser/pp.lua:152 +str = str .. ", " .. exp2str(exp[i]) -- ./candran/can-parser/pp.lua:153 +end -- ./candran/can-parser/pp.lua:153 +end -- ./candran/can-parser/pp.lua:153 +str = str .. " }" -- ./candran/can-parser/pp.lua:156 +elseif tag == "Invoke" then -- ./candran/can-parser/pp.lua:157 +str = str .. "{ " -- ./candran/can-parser/pp.lua:158 +str = str .. exp2str(exp[1]) .. ", " -- ./candran/can-parser/pp.lua:159 +str = str .. exp2str(exp[2]) -- ./candran/can-parser/pp.lua:160 +if exp[3] then -- ./candran/can-parser/pp.lua:161 +for i = 3, # exp do -- ./candran/can-parser/pp.lua:162 +str = str .. ", " .. exp2str(exp[i]) -- ./candran/can-parser/pp.lua:163 +end -- ./candran/can-parser/pp.lua:163 +end -- ./candran/can-parser/pp.lua:163 +str = str .. " }" -- ./candran/can-parser/pp.lua:166 +elseif tag == "Id" or tag == "Index" then -- ./candran/can-parser/pp.lua:168 +str = var2str(exp) -- ./candran/can-parser/pp.lua:169 +else -- ./candran/can-parser/pp.lua:169 +error("expecting an expression, but got a " .. tag) -- ./candran/can-parser/pp.lua:171 +end -- ./candran/can-parser/pp.lua:171 +return str -- ./candran/can-parser/pp.lua:173 +end -- ./candran/can-parser/pp.lua:173 +explist2str = function(explist) -- ./candran/can-parser/pp.lua:176 +local l = {} -- ./candran/can-parser/pp.lua:177 +for k, v in ipairs(explist) do -- ./candran/can-parser/pp.lua:178 +l[k] = exp2str(v) -- ./candran/can-parser/pp.lua:179 +end -- ./candran/can-parser/pp.lua:179 +if # l > 0 then -- ./candran/can-parser/pp.lua:181 +return "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:182 +else -- ./candran/can-parser/pp.lua:182 +return "" -- ./candran/can-parser/pp.lua:184 +end -- ./candran/can-parser/pp.lua:184 +end -- ./candran/can-parser/pp.lua:184 +stm2str = function(stm) -- ./candran/can-parser/pp.lua:188 +local tag = stm["tag"] -- ./candran/can-parser/pp.lua:189 +local str = "`" .. tag -- ./candran/can-parser/pp.lua:190 +if tag == "Do" then -- ./candran/can-parser/pp.lua:191 +local l = {} -- ./candran/can-parser/pp.lua:192 +for k, v in ipairs(stm) do -- ./candran/can-parser/pp.lua:193 +l[k] = stm2str(v) -- ./candran/can-parser/pp.lua:194 +end -- ./candran/can-parser/pp.lua:194 +str = str .. "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:196 +elseif tag == "Set" then -- ./candran/can-parser/pp.lua:197 +str = str .. "{ " -- ./candran/can-parser/pp.lua:198 +str = str .. varlist2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:199 +str = str .. explist2str(stm[2]) -- ./candran/can-parser/pp.lua:200 +str = str .. " }" -- ./candran/can-parser/pp.lua:201 +elseif tag == "While" then -- ./candran/can-parser/pp.lua:202 +str = str .. "{ " -- ./candran/can-parser/pp.lua:203 +str = str .. exp2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:204 +str = str .. block2str(stm[2]) -- ./candran/can-parser/pp.lua:205 +str = str .. " }" -- ./candran/can-parser/pp.lua:206 +elseif tag == "Repeat" then -- ./candran/can-parser/pp.lua:207 +str = str .. "{ " -- ./candran/can-parser/pp.lua:208 +str = str .. block2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:209 +str = str .. exp2str(stm[2]) -- ./candran/can-parser/pp.lua:210 +str = str .. " }" -- ./candran/can-parser/pp.lua:211 +elseif tag == "If" then -- ./candran/can-parser/pp.lua:212 +str = str .. "{ " -- ./candran/can-parser/pp.lua:213 +local len = # stm -- ./candran/can-parser/pp.lua:214 +if len % 2 == 0 then -- ./candran/can-parser/pp.lua:215 +local l = {} -- ./candran/can-parser/pp.lua:216 +for i = 1, len - 2, 2 do -- ./candran/can-parser/pp.lua:217 +str = str .. exp2str(stm[i]) .. ", " .. block2str(stm[i + 1]) .. ", " -- ./candran/can-parser/pp.lua:218 +end -- ./candran/can-parser/pp.lua:218 +str = str .. exp2str(stm[len - 1]) .. ", " .. block2str(stm[len]) -- ./candran/can-parser/pp.lua:220 +else -- ./candran/can-parser/pp.lua:220 +local l = {} -- ./candran/can-parser/pp.lua:222 +for i = 1, len - 3, 2 do -- ./candran/can-parser/pp.lua:223 +str = str .. exp2str(stm[i]) .. ", " .. block2str(stm[i + 1]) .. ", " -- ./candran/can-parser/pp.lua:224 +end -- ./candran/can-parser/pp.lua:224 +str = str .. exp2str(stm[len - 2]) .. ", " .. block2str(stm[len - 1]) .. ", " -- ./candran/can-parser/pp.lua:226 +str = str .. block2str(stm[len]) -- ./candran/can-parser/pp.lua:227 +end -- ./candran/can-parser/pp.lua:227 +str = str .. " }" -- ./candran/can-parser/pp.lua:229 +elseif tag == "Fornum" then -- ./candran/can-parser/pp.lua:230 +str = str .. "{ " -- ./candran/can-parser/pp.lua:231 +str = str .. var2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:232 +str = str .. exp2str(stm[2]) .. ", " -- ./candran/can-parser/pp.lua:233 +str = str .. exp2str(stm[3]) .. ", " -- ./candran/can-parser/pp.lua:234 +if stm[5] then -- ./candran/can-parser/pp.lua:235 +str = str .. exp2str(stm[4]) .. ", " -- ./candran/can-parser/pp.lua:236 +str = str .. block2str(stm[5]) -- ./candran/can-parser/pp.lua:237 +else -- ./candran/can-parser/pp.lua:237 +str = str .. block2str(stm[4]) -- ./candran/can-parser/pp.lua:239 +end -- ./candran/can-parser/pp.lua:239 +str = str .. " }" -- ./candran/can-parser/pp.lua:241 +elseif tag == "Forin" then -- ./candran/can-parser/pp.lua:242 +str = str .. "{ " -- ./candran/can-parser/pp.lua:243 +str = str .. varlist2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:244 +str = str .. explist2str(stm[2]) .. ", " -- ./candran/can-parser/pp.lua:245 +str = str .. block2str(stm[3]) -- ./candran/can-parser/pp.lua:246 +str = str .. " }" -- ./candran/can-parser/pp.lua:247 +elseif tag == "Local" then -- ./candran/can-parser/pp.lua:248 +str = str .. "{ " -- ./candran/can-parser/pp.lua:249 +str = str .. varlist2str(stm[1]) -- ./candran/can-parser/pp.lua:250 +if # stm[2] > 0 then -- ./candran/can-parser/pp.lua:251 +str = str .. ", " .. explist2str(stm[2]) -- ./candran/can-parser/pp.lua:252 +else -- ./candran/can-parser/pp.lua:252 +str = str .. ", " .. "{ }" -- ./candran/can-parser/pp.lua:254 +end -- ./candran/can-parser/pp.lua:254 +str = str .. " }" -- ./candran/can-parser/pp.lua:256 +elseif tag == "Localrec" then -- ./candran/can-parser/pp.lua:257 +str = str .. "{ " -- ./candran/can-parser/pp.lua:258 +str = str .. "{ " .. var2str(stm[1][1]) .. " }, " -- ./candran/can-parser/pp.lua:259 +str = str .. "{ " .. exp2str(stm[2][1]) .. " }" -- ./candran/can-parser/pp.lua:260 +str = str .. " }" -- ./candran/can-parser/pp.lua:261 +elseif tag == "Goto" or tag == "Label" then -- ./candran/can-parser/pp.lua:263 +str = str .. "{ " .. name2str(stm[1]) .. " }" -- ./candran/can-parser/pp.lua:264 +elseif tag == "Return" then -- ./candran/can-parser/pp.lua:265 +str = str .. explist2str(stm) -- ./candran/can-parser/pp.lua:266 +elseif tag == "Break" then -- ./candran/can-parser/pp.lua:267 + -- ./candran/can-parser/pp.lua:268 +elseif tag == "Call" then -- ./candran/can-parser/pp.lua:268 +str = str .. "{ " -- ./candran/can-parser/pp.lua:269 +str = str .. exp2str(stm[1]) -- ./candran/can-parser/pp.lua:270 +if stm[2] then -- ./candran/can-parser/pp.lua:271 +for i = 2, # stm do -- ./candran/can-parser/pp.lua:272 +str = str .. ", " .. exp2str(stm[i]) -- ./candran/can-parser/pp.lua:273 +end -- ./candran/can-parser/pp.lua:273 +end -- ./candran/can-parser/pp.lua:273 +str = str .. " }" -- ./candran/can-parser/pp.lua:276 +elseif tag == "Invoke" then -- ./candran/can-parser/pp.lua:277 +str = str .. "{ " -- ./candran/can-parser/pp.lua:278 +str = str .. exp2str(stm[1]) .. ", " -- ./candran/can-parser/pp.lua:279 +str = str .. exp2str(stm[2]) -- ./candran/can-parser/pp.lua:280 +if stm[3] then -- ./candran/can-parser/pp.lua:281 +for i = 3, # stm do -- ./candran/can-parser/pp.lua:282 +str = str .. ", " .. exp2str(stm[i]) -- ./candran/can-parser/pp.lua:283 +end -- ./candran/can-parser/pp.lua:283 +end -- ./candran/can-parser/pp.lua:283 +str = str .. " }" -- ./candran/can-parser/pp.lua:286 +else -- ./candran/can-parser/pp.lua:286 +error("expecting a statement, but got a " .. tag) -- ./candran/can-parser/pp.lua:288 +end -- ./candran/can-parser/pp.lua:288 +return str -- ./candran/can-parser/pp.lua:290 +end -- ./candran/can-parser/pp.lua:290 +block2str = function(block) -- ./candran/can-parser/pp.lua:293 +local l = {} -- ./candran/can-parser/pp.lua:294 +for k, v in ipairs(block) do -- ./candran/can-parser/pp.lua:295 +l[k] = stm2str(v) -- ./candran/can-parser/pp.lua:296 +end -- ./candran/can-parser/pp.lua:296 +return "{ " .. table["concat"](l, ", ") .. " }" -- ./candran/can-parser/pp.lua:298 +end -- ./candran/can-parser/pp.lua:298 +pp["tostring"] = function(t) -- ./candran/can-parser/pp.lua:301 +assert(type(t) == "table") -- ./candran/can-parser/pp.lua:302 +return block2str(t) -- ./candran/can-parser/pp.lua:303 +end -- ./candran/can-parser/pp.lua:303 +pp["print"] = function(t) -- ./candran/can-parser/pp.lua:306 +assert(type(t) == "table") -- ./candran/can-parser/pp.lua:307 +print(pp["tostring"](t)) -- ./candran/can-parser/pp.lua:308 +end -- ./candran/can-parser/pp.lua:308 +pp["dump"] = function(t, i) -- ./candran/can-parser/pp.lua:311 +if i == nil then -- ./candran/can-parser/pp.lua:312 +i = 0 -- ./candran/can-parser/pp.lua:312 +end -- ./candran/can-parser/pp.lua:312 io["write"](string["format"]("{\ -")) -- ./lib/lua-parser/pp.lua:313 +")) -- ./candran/can-parser/pp.lua:313 io["write"](string["format"]("%s[tag] = %s\ -", string["rep"](" ", i + 2), t["tag"] or "nil")) -- ./lib/lua-parser/pp.lua:314 +", string["rep"](" ", i + 2), t["tag"] or "nil")) -- ./candran/can-parser/pp.lua:314 io["write"](string["format"]("%s[pos] = %s\ -", string["rep"](" ", i + 2), t["pos"] or "nil")) -- ./lib/lua-parser/pp.lua:315 -for k, v in ipairs(t) do -- ./lib/lua-parser/pp.lua:316 -io["write"](string["format"]("%s[%s] = ", string["rep"](" ", i + 2), tostring(k))) -- ./lib/lua-parser/pp.lua:317 -if type(v) == "table" then -- ./lib/lua-parser/pp.lua:318 -pp["dump"](v, i + 2) -- ./lib/lua-parser/pp.lua:319 -else -- ./lib/lua-parser/pp.lua:319 +", string["rep"](" ", i + 2), t["pos"] or "nil")) -- ./candran/can-parser/pp.lua:315 +for k, v in ipairs(t) do -- ./candran/can-parser/pp.lua:316 +io["write"](string["format"]("%s[%s] = ", string["rep"](" ", i + 2), tostring(k))) -- ./candran/can-parser/pp.lua:317 +if type(v) == "table" then -- ./candran/can-parser/pp.lua:318 +pp["dump"](v, i + 2) -- ./candran/can-parser/pp.lua:319 +else -- ./candran/can-parser/pp.lua:319 io["write"](string["format"]("%s\ -", tostring(v))) -- ./lib/lua-parser/pp.lua:321 -end -- ./lib/lua-parser/pp.lua:321 -end -- ./lib/lua-parser/pp.lua:321 +", tostring(v))) -- ./candran/can-parser/pp.lua:321 +end -- ./candran/can-parser/pp.lua:321 +end -- ./candran/can-parser/pp.lua:321 io["write"](string["format"]("%s}\ -", string["rep"](" ", i))) -- ./lib/lua-parser/pp.lua:324 -end -- ./lib/lua-parser/pp.lua:324 -return pp -- ./lib/lua-parser/pp.lua:327 -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: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 -"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: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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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: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 -"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 -"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 -"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 -"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 -"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 -"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: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 -"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 -"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 -"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 -"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 -"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: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 -"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 -"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 -"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 -"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 -"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: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 -"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 -"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 -"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: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 -"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: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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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 -"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: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 -"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 -"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 -"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 -"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 -"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: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: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 -"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 -"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 -"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: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 -"ErrCBraceDestructuring", -- ./lib/lua-parser/parser.lua:167 -"expected '}' to close the destructuring variable list" -- ./lib/lua-parser/parser.lua:167 -}, -- ./lib/lua-parser/parser.lua:167 -{ -- ./lib/lua-parser/parser.lua:168 -"ErrDestructuringEqField", -- ./lib/lua-parser/parser.lua:168 -"expected '=' after the table key in destructuring variable list" -- ./lib/lua-parser/parser.lua:168 -}, -- ./lib/lua-parser/parser.lua:168 -{ -- ./lib/lua-parser/parser.lua:169 -"ErrDestructuringExprField", -- ./lib/lua-parser/parser.lua:169 -"expected an identifier after '=' in destructuring variable list" -- ./lib/lua-parser/parser.lua:169 -}, -- ./lib/lua-parser/parser.lua:169 -{ -- ./lib/lua-parser/parser.lua:171 -"ErrCBracketTableCompr", -- ./lib/lua-parser/parser.lua:171 -"expected ']' to close the table comprehension" -- ./lib/lua-parser/parser.lua:171 -}, -- ./lib/lua-parser/parser.lua:171 -{ -- ./lib/lua-parser/parser.lua:173 -"ErrDigitHex", -- ./lib/lua-parser/parser.lua:173 -"expected one or more hexadecimal digits after '0x'" -- ./lib/lua-parser/parser.lua:173 -}, -- ./lib/lua-parser/parser.lua:173 -{ -- ./lib/lua-parser/parser.lua:174 -"ErrDigitDeci", -- ./lib/lua-parser/parser.lua:174 -"expected one or more digits after the decimal point" -- ./lib/lua-parser/parser.lua:174 -}, -- ./lib/lua-parser/parser.lua:174 -{ -- ./lib/lua-parser/parser.lua:175 -"ErrDigitExpo", -- ./lib/lua-parser/parser.lua:175 -"expected one or more digits for the exponent" -- ./lib/lua-parser/parser.lua:175 -}, -- ./lib/lua-parser/parser.lua:175 -{ -- ./lib/lua-parser/parser.lua:177 -"ErrQuote", -- ./lib/lua-parser/parser.lua:177 -"unclosed string" -- ./lib/lua-parser/parser.lua:177 -}, -- ./lib/lua-parser/parser.lua:177 -{ -- ./lib/lua-parser/parser.lua:178 -"ErrHexEsc", -- ./lib/lua-parser/parser.lua:178 -"expected exactly two hexadecimal digits after '\\x'" -- ./lib/lua-parser/parser.lua:178 -}, -- ./lib/lua-parser/parser.lua:178 -{ -- ./lib/lua-parser/parser.lua:179 -"ErrOBraceUEsc", -- ./lib/lua-parser/parser.lua:179 -"expected '{' after '\\u'" -- ./lib/lua-parser/parser.lua:179 -}, -- ./lib/lua-parser/parser.lua:179 -{ -- ./lib/lua-parser/parser.lua:180 -"ErrDigitUEsc", -- ./lib/lua-parser/parser.lua:180 -"expected one or more hexadecimal digits for the UTF-8 code point" -- ./lib/lua-parser/parser.lua:180 -}, -- ./lib/lua-parser/parser.lua:180 -{ -- ./lib/lua-parser/parser.lua:181 -"ErrCBraceUEsc", -- ./lib/lua-parser/parser.lua:181 -"expected '}' after the code point" -- ./lib/lua-parser/parser.lua:181 -}, -- ./lib/lua-parser/parser.lua:181 -{ -- ./lib/lua-parser/parser.lua:182 -"ErrEscSeq", -- ./lib/lua-parser/parser.lua:182 -"invalid escape sequence" -- ./lib/lua-parser/parser.lua:182 -}, -- ./lib/lua-parser/parser.lua:182 -{ -- ./lib/lua-parser/parser.lua:183 -"ErrCloseLStr", -- ./lib/lua-parser/parser.lua:183 -"unclosed long string" -- ./lib/lua-parser/parser.lua:183 -} -- ./lib/lua-parser/parser.lua:183 -} -- ./lib/lua-parser/parser.lua:183 -local function throw(label) -- ./lib/lua-parser/parser.lua:186 -label = "Err" .. label -- ./lib/lua-parser/parser.lua:187 -for i, labelinfo in ipairs(labels) do -- ./lib/lua-parser/parser.lua:188 -if labelinfo[1] == label then -- ./lib/lua-parser/parser.lua:189 -return T(i) -- ./lib/lua-parser/parser.lua:190 -end -- ./lib/lua-parser/parser.lua:190 -end -- ./lib/lua-parser/parser.lua:190 -error("Label not found: " .. label) -- ./lib/lua-parser/parser.lua:194 -end -- ./lib/lua-parser/parser.lua:194 -local function expect(patt, label) -- ./lib/lua-parser/parser.lua:197 -return patt + throw(label) -- ./lib/lua-parser/parser.lua:198 -end -- ./lib/lua-parser/parser.lua:198 -local function token(patt) -- ./lib/lua-parser/parser.lua:204 -return patt * V("Skip") -- ./lib/lua-parser/parser.lua:205 -end -- ./lib/lua-parser/parser.lua:205 -local function sym(str) -- ./lib/lua-parser/parser.lua:208 -return token(P(str)) -- ./lib/lua-parser/parser.lua:209 -end -- ./lib/lua-parser/parser.lua:209 -local function kw(str) -- ./lib/lua-parser/parser.lua:212 -return token(P(str) * - V("IdRest")) -- ./lib/lua-parser/parser.lua:213 -end -- ./lib/lua-parser/parser.lua:213 -local function tagC(tag, patt) -- ./lib/lua-parser/parser.lua:216 -return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./lib/lua-parser/parser.lua:217 -end -- ./lib/lua-parser/parser.lua:217 -local function unaryOp(op, e) -- ./lib/lua-parser/parser.lua:220 -return { -- ./lib/lua-parser/parser.lua:221 -["tag"] = "Op", -- ./lib/lua-parser/parser.lua:221 -["pos"] = e["pos"], -- ./lib/lua-parser/parser.lua:221 -[1] = op, -- ./lib/lua-parser/parser.lua:221 -[2] = e -- ./lib/lua-parser/parser.lua:221 -} -- ./lib/lua-parser/parser.lua:221 -end -- ./lib/lua-parser/parser.lua:221 -local function binaryOp(e1, op, e2) -- ./lib/lua-parser/parser.lua:224 -if not op then -- ./lib/lua-parser/parser.lua:225 -return e1 -- ./lib/lua-parser/parser.lua:226 -else -- ./lib/lua-parser/parser.lua:226 -return { -- ./lib/lua-parser/parser.lua:228 -["tag"] = "Op", -- ./lib/lua-parser/parser.lua:228 -["pos"] = e1["pos"], -- ./lib/lua-parser/parser.lua:228 -[1] = op, -- ./lib/lua-parser/parser.lua:228 -[2] = e1, -- ./lib/lua-parser/parser.lua:228 -[3] = e2 -- ./lib/lua-parser/parser.lua:228 -} -- ./lib/lua-parser/parser.lua:228 -end -- ./lib/lua-parser/parser.lua:228 -end -- ./lib/lua-parser/parser.lua:228 -local function sepBy(patt, sep, label) -- ./lib/lua-parser/parser.lua:232 -if label then -- ./lib/lua-parser/parser.lua:233 -return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./lib/lua-parser/parser.lua:234 -else -- ./lib/lua-parser/parser.lua:234 -return patt * Cg(sep * patt) ^ 0 -- ./lib/lua-parser/parser.lua:236 -end -- ./lib/lua-parser/parser.lua:236 -end -- ./lib/lua-parser/parser.lua:236 -local function chainOp(patt, sep, label) -- ./lib/lua-parser/parser.lua:240 -return Cf(sepBy(patt, sep, label), binaryOp) -- ./lib/lua-parser/parser.lua:241 -end -- ./lib/lua-parser/parser.lua:241 -local function commaSep(patt, label) -- ./lib/lua-parser/parser.lua:244 -return sepBy(patt, sym(","), label) -- ./lib/lua-parser/parser.lua:245 -end -- ./lib/lua-parser/parser.lua:245 -local function tagDo(block) -- ./lib/lua-parser/parser.lua:248 -block["tag"] = "Do" -- ./lib/lua-parser/parser.lua:249 -return block -- ./lib/lua-parser/parser.lua:250 -end -- ./lib/lua-parser/parser.lua:250 -local function fixFuncStat(func) -- ./lib/lua-parser/parser.lua:253 -if func[1]["is_method"] then -- ./lib/lua-parser/parser.lua:254 -table["insert"](func[2][1], 1, { -- ./lib/lua-parser/parser.lua:254 -["tag"] = "Id", -- ./lib/lua-parser/parser.lua:254 -[1] = "self" -- ./lib/lua-parser/parser.lua:254 -}) -- ./lib/lua-parser/parser.lua:254 -end -- ./lib/lua-parser/parser.lua:254 -func[1] = { func[1] } -- ./lib/lua-parser/parser.lua:255 -func[2] = { func[2] } -- ./lib/lua-parser/parser.lua:256 -return func -- ./lib/lua-parser/parser.lua:257 -end -- ./lib/lua-parser/parser.lua:257 -local function addDots(params, dots) -- ./lib/lua-parser/parser.lua:260 -if dots then -- ./lib/lua-parser/parser.lua:261 -table["insert"](params, dots) -- ./lib/lua-parser/parser.lua:261 -end -- ./lib/lua-parser/parser.lua:261 -return params -- ./lib/lua-parser/parser.lua:262 -end -- ./lib/lua-parser/parser.lua:262 -local function insertIndex(t, index) -- ./lib/lua-parser/parser.lua:265 -return { -- ./lib/lua-parser/parser.lua:266 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:266 -["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:266 -[1] = t, -- ./lib/lua-parser/parser.lua:266 -[2] = index -- ./lib/lua-parser/parser.lua:266 -} -- ./lib/lua-parser/parser.lua:266 -end -- ./lib/lua-parser/parser.lua:266 -local function markMethod(t, method) -- ./lib/lua-parser/parser.lua:269 -if method then -- ./lib/lua-parser/parser.lua:270 -return { -- ./lib/lua-parser/parser.lua:271 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:271 -["pos"] = t["pos"], -- ./lib/lua-parser/parser.lua:271 -["is_method"] = true, -- ./lib/lua-parser/parser.lua:271 -[1] = t, -- ./lib/lua-parser/parser.lua:271 -[2] = method -- ./lib/lua-parser/parser.lua:271 -} -- ./lib/lua-parser/parser.lua:271 -end -- ./lib/lua-parser/parser.lua:271 -return t -- ./lib/lua-parser/parser.lua:273 -end -- ./lib/lua-parser/parser.lua:273 -local function makeSuffixedExpr(t1, t2) -- ./lib/lua-parser/parser.lua:276 -if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./lib/lua-parser/parser.lua:277 -local t = { -- ./lib/lua-parser/parser.lua:278 -["tag"] = t2["tag"], -- ./lib/lua-parser/parser.lua:278 -["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:278 -[1] = t1 -- ./lib/lua-parser/parser.lua:278 -} -- ./lib/lua-parser/parser.lua:278 -for k, v in ipairs(t2) do -- ./lib/lua-parser/parser.lua:279 -table["insert"](t, v) -- ./lib/lua-parser/parser.lua:280 -end -- ./lib/lua-parser/parser.lua:280 -return t -- ./lib/lua-parser/parser.lua:282 -elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./lib/lua-parser/parser.lua:283 -return { -- ./lib/lua-parser/parser.lua:284 -["tag"] = t2["tag"], -- ./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 -elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./lib/lua-parser/parser.lua:285 -return { -- ./lib/lua-parser/parser.lua:286 -["tag"] = "SafeIndex", -- ./lib/lua-parser/parser.lua:286 -["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:286 -[1] = t1, -- ./lib/lua-parser/parser.lua:286 -[2] = t2[1] -- ./lib/lua-parser/parser.lua:286 -} -- ./lib/lua-parser/parser.lua:286 -elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./lib/lua-parser/parser.lua:287 -return { -- ./lib/lua-parser/parser.lua:288 -["tag"] = "Index", -- ./lib/lua-parser/parser.lua:288 -["pos"] = t1["pos"], -- ./lib/lua-parser/parser.lua:288 -[1] = t1, -- ./lib/lua-parser/parser.lua:288 -[2] = t2[1] -- ./lib/lua-parser/parser.lua:288 -} -- ./lib/lua-parser/parser.lua:288 -else -- ./lib/lua-parser/parser.lua:288 -error("unexpected tag in suffixed expression") -- ./lib/lua-parser/parser.lua:290 -end -- ./lib/lua-parser/parser.lua:290 -end -- ./lib/lua-parser/parser.lua:290 -local function fixShortFunc(t) -- ./lib/lua-parser/parser.lua:294 -if t[1] == ":" then -- self method -- ./lib/lua-parser/parser.lua:295 -table["insert"](t[2], 1, { -- ./lib/lua-parser/parser.lua:296 -["tag"] = "Id", -- ./lib/lua-parser/parser.lua:296 -"self" -- ./lib/lua-parser/parser.lua:296 -}) -- ./lib/lua-parser/parser.lua:296 -table["remove"](t, 1) -- ./lib/lua-parser/parser.lua:297 -t["is_method"] = true -- ./lib/lua-parser/parser.lua:298 -end -- ./lib/lua-parser/parser.lua:298 -t["is_short"] = true -- ./lib/lua-parser/parser.lua:300 -return t -- ./lib/lua-parser/parser.lua:301 -end -- ./lib/lua-parser/parser.lua:301 -local function statToExpr(t) -- tag a StatExpr -- ./lib/lua-parser/parser.lua:304 -t["tag"] = t["tag"] .. "Expr" -- ./lib/lua-parser/parser.lua:305 -return t -- ./lib/lua-parser/parser.lua:306 -end -- ./lib/lua-parser/parser.lua:306 -local function fixStructure(t) -- fix the AST structure if needed -- ./lib/lua-parser/parser.lua:309 -local i = 1 -- ./lib/lua-parser/parser.lua:310 -while i <= # t do -- ./lib/lua-parser/parser.lua:311 -if type(t[i]) == "table" then -- ./lib/lua-parser/parser.lua:312 -fixStructure(t[i]) -- ./lib/lua-parser/parser.lua:313 -for j = # t[i], 1, - 1 do -- ./lib/lua-parser/parser.lua:314 -local stat = t[i][j] -- ./lib/lua-parser/parser.lua:315 -if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./lib/lua-parser/parser.lua:316 -table["remove"](t[i], j) -- ./lib/lua-parser/parser.lua:317 -table["insert"](t, i + 1, stat) -- ./lib/lua-parser/parser.lua:318 -if t["tag"] == "Block" or t["tag"] == "Do" then -- ./lib/lua-parser/parser.lua:319 -stat["move_up_block"] = stat["move_up_block"] - 1 -- ./lib/lua-parser/parser.lua:320 -end -- ./lib/lua-parser/parser.lua:320 -end -- ./lib/lua-parser/parser.lua:320 -end -- ./lib/lua-parser/parser.lua:320 -end -- ./lib/lua-parser/parser.lua:320 -i = i + 1 -- ./lib/lua-parser/parser.lua:325 -end -- ./lib/lua-parser/parser.lua:325 -return t -- ./lib/lua-parser/parser.lua:327 -end -- ./lib/lua-parser/parser.lua:327 -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:330 -for i, stat in ipairs(block) do -- ./lib/lua-parser/parser.lua:331 -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:333 -local exprlist -- ./lib/lua-parser/parser.lua:334 -if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./lib/lua-parser/parser.lua:336 -exprlist = stat[# stat] -- ./lib/lua-parser/parser.lua:337 -elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./lib/lua-parser/parser.lua:338 -exprlist = stat -- ./lib/lua-parser/parser.lua:339 -end -- ./lib/lua-parser/parser.lua:339 -local last = exprlist[# exprlist] -- last value in ExprList -- ./lib/lua-parser/parser.lua:342 -if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./lib/lua-parser/parser.lua:346 -local p = i -- ./lib/lua-parser/parser.lua:347 -for j, fstat in ipairs(last[2]) do -- ./lib/lua-parser/parser.lua:348 -p = i + j -- ./lib/lua-parser/parser.lua:349 -table["insert"](block, p, fstat) -- copy stats from func body to block -- ./lib/lua-parser/parser.lua:350 -if stat["move_up_block"] then -- extracted stats inherit move_up_block from statement -- ./lib/lua-parser/parser.lua:352 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./lib/lua-parser/parser.lua:353 -end -- ./lib/lua-parser/parser.lua:353 -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:356 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:357 -end -- ./lib/lua-parser/parser.lua:357 -end -- ./lib/lua-parser/parser.lua:357 -exprlist[# exprlist] = last[1] -- replace func with paren and expressions -- ./lib/lua-parser/parser.lua:361 -exprlist[# exprlist]["tag"] = "Paren" -- ./lib/lua-parser/parser.lua:362 -if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:364 -for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:365 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:366 -end -- ./lib/lua-parser/parser.lua:366 -end -- ./lib/lua-parser/parser.lua:366 -return block, i -- ./lib/lua-parser/parser.lua:370 -elseif last["tag"]:match("Expr$") then -- ./lib/lua-parser/parser.lua:373 -local r = searchEndRec({ last }) -- ./lib/lua-parser/parser.lua:374 -if r then -- ./lib/lua-parser/parser.lua:375 -for j = 2, # r, 1 do -- ./lib/lua-parser/parser.lua:376 -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:377 -end -- move back superflous statements from our new table to our real block -- ./lib/lua-parser/parser.lua:377 -return block, i -- ./lib/lua-parser/parser.lua:379 -end -- ./lib/lua-parser/parser.lua:379 -elseif last["tag"] == "Function" then -- ./lib/lua-parser/parser.lua:381 -local r = searchEndRec(last[2]) -- ./lib/lua-parser/parser.lua:382 -if r then -- ./lib/lua-parser/parser.lua:383 -return block, i -- ./lib/lua-parser/parser.lua:384 -end -- ./lib/lua-parser/parser.lua:384 -end -- ./lib/lua-parser/parser.lua:384 -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:389 -local blocks -- ./lib/lua-parser/parser.lua:390 -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:392 -blocks = stat -- ./lib/lua-parser/parser.lua:393 -elseif stat["tag"]:match("^Do") then -- ./lib/lua-parser/parser.lua:394 -blocks = { stat } -- ./lib/lua-parser/parser.lua:395 -end -- ./lib/lua-parser/parser.lua:395 -for _, iblock in ipairs(blocks) do -- ./lib/lua-parser/parser.lua:398 -if iblock["tag"] == "Block" then -- blocks -- ./lib/lua-parser/parser.lua:399 -local oldLen = # iblock -- ./lib/lua-parser/parser.lua:400 -local newiBlock, newEnd = searchEndRec(iblock, true) -- ./lib/lua-parser/parser.lua:401 -if newiBlock then -- if end in the block -- ./lib/lua-parser/parser.lua:402 -local p = i -- ./lib/lua-parser/parser.lua:403 -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:404 -p = p + 1 -- ./lib/lua-parser/parser.lua:405 -table["insert"](block, p, iblock[j]) -- ./lib/lua-parser/parser.lua:406 -iblock[j] = nil -- ./lib/lua-parser/parser.lua:407 -end -- ./lib/lua-parser/parser.lua:407 -if not isRecCall then -- if superfluous statements won't be moved in a next recursion, let fixStructure handle things -- ./lib/lua-parser/parser.lua:410 -for j = p + 1, # block, 1 do -- ./lib/lua-parser/parser.lua:411 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./lib/lua-parser/parser.lua:412 -end -- ./lib/lua-parser/parser.lua:412 -end -- ./lib/lua-parser/parser.lua:412 -return block, i -- ./lib/lua-parser/parser.lua:416 -end -- ./lib/lua-parser/parser.lua:416 -end -- ./lib/lua-parser/parser.lua:416 -end -- ./lib/lua-parser/parser.lua:416 -end -- ./lib/lua-parser/parser.lua:416 -end -- ./lib/lua-parser/parser.lua:416 -return nil -- ./lib/lua-parser/parser.lua:422 -end -- ./lib/lua-parser/parser.lua:422 -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:425 -local r = searchEndRec(fixStructure(t)) -- ./lib/lua-parser/parser.lua:426 -if not r then -- ./lib/lua-parser/parser.lua:427 -return false -- ./lib/lua-parser/parser.lua:428 -end -- ./lib/lua-parser/parser.lua:428 -return true, r -- ./lib/lua-parser/parser.lua:430 -end -- ./lib/lua-parser/parser.lua:430 -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- will try a SingleStat if start doesn't match -- ./lib/lua-parser/parser.lua:433 -if canFollow then -- ./lib/lua-parser/parser.lua:434 -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:437 -else -- ./lib/lua-parser/parser.lua:437 -return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./lib/lua-parser/parser.lua:441 -end -- ./lib/lua-parser/parser.lua:441 -end -- ./lib/lua-parser/parser.lua:441 -local function expectBlockWithEnd(label) -- can't work *optionnaly* with SingleStat unfortunatly -- ./lib/lua-parser/parser.lua:445 -return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./lib/lua-parser/parser.lua:447 -end -- ./lib/lua-parser/parser.lua:447 -local function maybeBlockWithEnd() -- same as above but don't error if it doesn't match -- ./lib/lua-parser/parser.lua:450 -return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./lib/lua-parser/parser.lua:452 -end -- ./lib/lua-parser/parser.lua:452 -local stacks = { ["lexpr"] = {} } -- ./lib/lua-parser/parser.lua:456 -local function push(f) -- ./lib/lua-parser/parser.lua:458 -return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:459 -table["insert"](stacks[f], true) -- ./lib/lua-parser/parser.lua:460 -return true -- ./lib/lua-parser/parser.lua:461 -end) -- ./lib/lua-parser/parser.lua:461 -end -- ./lib/lua-parser/parser.lua:461 -local function pop(f) -- ./lib/lua-parser/parser.lua:464 -return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:465 -table["remove"](stacks[f]) -- ./lib/lua-parser/parser.lua:466 -return true -- ./lib/lua-parser/parser.lua:467 -end) -- ./lib/lua-parser/parser.lua:467 -end -- ./lib/lua-parser/parser.lua:467 -local function when(f) -- ./lib/lua-parser/parser.lua:470 -return Cmt(P(""), function() -- ./lib/lua-parser/parser.lua:471 -return # stacks[f] > 0 -- ./lib/lua-parser/parser.lua:472 -end) -- ./lib/lua-parser/parser.lua:472 -end -- ./lib/lua-parser/parser.lua:472 -local function set(f, patt) -- patt *must* succeed (or throw an error) to preserve stack integrity -- ./lib/lua-parser/parser.lua:475 -return push(f) * patt * pop(f) -- ./lib/lua-parser/parser.lua:476 -end -- ./lib/lua-parser/parser.lua:476 -local G = { -- ./lib/lua-parser/parser.lua:480 -V("Lua"), -- ./lib/lua-parser/parser.lua:480 -["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./lib/lua-parser/parser.lua:481 +", string["rep"](" ", i))) -- ./candran/can-parser/pp.lua:324 +end -- ./candran/can-parser/pp.lua:324 +return pp -- ./candran/can-parser/pp.lua:327 +end -- ./candran/can-parser/pp.lua:327 +local pp = _() or pp -- ./candran/can-parser/pp.lua:331 +package["loaded"]["candran.can-parser.pp"] = pp or true -- ./candran/can-parser/pp.lua:332 +local function _() -- ./candran/can-parser/pp.lua:335 +local lpeg = require("lpeglabel") -- ./candran/can-parser/parser.lua:72 +lpeg["locale"](lpeg) -- ./candran/can-parser/parser.lua:74 +local P, S, V = lpeg["P"], lpeg["S"], lpeg["V"] -- ./candran/can-parser/parser.lua:76 +local C, Carg, Cb, Cc = lpeg["C"], lpeg["Carg"], lpeg["Cb"], lpeg["Cc"] -- ./candran/can-parser/parser.lua:77 +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg["Cf"], lpeg["Cg"], lpeg["Cmt"], lpeg["Cp"], lpeg["Cs"], lpeg["Ct"] -- ./candran/can-parser/parser.lua:78 +local Rec, T = lpeg["Rec"], lpeg["T"] -- ./candran/can-parser/parser.lua:79 +local alpha, digit, alnum = lpeg["alpha"], lpeg["digit"], lpeg["alnum"] -- ./candran/can-parser/parser.lua:81 +local xdigit = lpeg["xdigit"] -- ./candran/can-parser/parser.lua:82 +local space = lpeg["space"] -- ./candran/can-parser/parser.lua:83 +local labels = { -- ./candran/can-parser/parser.lua:88 +{ -- ./candran/can-parser/parser.lua:89 +"ErrExtra", -- ./candran/can-parser/parser.lua:89 +"unexpected character(s), expected EOF" -- ./candran/can-parser/parser.lua:89 +}, -- ./candran/can-parser/parser.lua:89 +{ -- ./candran/can-parser/parser.lua:90 +"ErrInvalidStat", -- ./candran/can-parser/parser.lua:90 +"unexpected token, invalid start of statement" -- ./candran/can-parser/parser.lua:90 +}, -- ./candran/can-parser/parser.lua:90 +{ -- ./candran/can-parser/parser.lua:92 +"ErrEndIf", -- ./candran/can-parser/parser.lua:92 +"expected 'end' to close the if statement" -- ./candran/can-parser/parser.lua:92 +}, -- ./candran/can-parser/parser.lua:92 +{ -- ./candran/can-parser/parser.lua:93 +"ErrExprIf", -- ./candran/can-parser/parser.lua:93 +"expected a condition after 'if'" -- ./candran/can-parser/parser.lua:93 +}, -- ./candran/can-parser/parser.lua:93 +{ -- ./candran/can-parser/parser.lua:94 +"ErrThenIf", -- ./candran/can-parser/parser.lua:94 +"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:94 +}, -- ./candran/can-parser/parser.lua:94 +{ -- ./candran/can-parser/parser.lua:95 +"ErrExprEIf", -- ./candran/can-parser/parser.lua:95 +"expected a condition after 'elseif'" -- ./candran/can-parser/parser.lua:95 +}, -- ./candran/can-parser/parser.lua:95 +{ -- ./candran/can-parser/parser.lua:96 +"ErrThenEIf", -- ./candran/can-parser/parser.lua:96 +"expected 'then' after the condition" -- ./candran/can-parser/parser.lua:96 +}, -- ./candran/can-parser/parser.lua:96 +{ -- ./candran/can-parser/parser.lua:98 +"ErrEndDo", -- ./candran/can-parser/parser.lua:98 +"expected 'end' to close the do block" -- ./candran/can-parser/parser.lua:98 +}, -- ./candran/can-parser/parser.lua:98 +{ -- ./candran/can-parser/parser.lua:99 +"ErrExprWhile", -- ./candran/can-parser/parser.lua:99 +"expected a condition after 'while'" -- ./candran/can-parser/parser.lua:99 +}, -- ./candran/can-parser/parser.lua:99 +{ -- ./candran/can-parser/parser.lua:100 +"ErrDoWhile", -- ./candran/can-parser/parser.lua:100 +"expected 'do' after the condition" -- ./candran/can-parser/parser.lua:100 +}, -- ./candran/can-parser/parser.lua:100 +{ -- ./candran/can-parser/parser.lua:101 +"ErrEndWhile", -- ./candran/can-parser/parser.lua:101 +"expected 'end' to close the while loop" -- ./candran/can-parser/parser.lua:101 +}, -- ./candran/can-parser/parser.lua:101 +{ -- ./candran/can-parser/parser.lua:102 +"ErrUntilRep", -- ./candran/can-parser/parser.lua:102 +"expected 'until' at the end of the repeat loop" -- ./candran/can-parser/parser.lua:102 +}, -- ./candran/can-parser/parser.lua:102 +{ -- ./candran/can-parser/parser.lua:103 +"ErrExprRep", -- ./candran/can-parser/parser.lua:103 +"expected a conditions after 'until'" -- ./candran/can-parser/parser.lua:103 +}, -- ./candran/can-parser/parser.lua:103 +{ -- ./candran/can-parser/parser.lua:105 +"ErrForRange", -- ./candran/can-parser/parser.lua:105 +"expected a numeric or generic range after 'for'" -- ./candran/can-parser/parser.lua:105 +}, -- ./candran/can-parser/parser.lua:105 +{ -- ./candran/can-parser/parser.lua:106 +"ErrEndFor", -- ./candran/can-parser/parser.lua:106 +"expected 'end' to close the for loop" -- ./candran/can-parser/parser.lua:106 +}, -- ./candran/can-parser/parser.lua:106 +{ -- ./candran/can-parser/parser.lua:107 +"ErrExprFor1", -- ./candran/can-parser/parser.lua:107 +"expected a starting expression for the numeric range" -- ./candran/can-parser/parser.lua:107 +}, -- ./candran/can-parser/parser.lua:107 +{ -- ./candran/can-parser/parser.lua:108 +"ErrCommaFor", -- ./candran/can-parser/parser.lua:108 +"expected ',' to split the start and end of the range" -- ./candran/can-parser/parser.lua:108 +}, -- ./candran/can-parser/parser.lua:108 +{ -- ./candran/can-parser/parser.lua:109 +"ErrExprFor2", -- ./candran/can-parser/parser.lua:109 +"expected an ending expression for the numeric range" -- ./candran/can-parser/parser.lua:109 +}, -- ./candran/can-parser/parser.lua:109 +{ -- ./candran/can-parser/parser.lua:110 +"ErrExprFor3", -- ./candran/can-parser/parser.lua:110 +"expected a step expression for the numeric range after ','" -- ./candran/can-parser/parser.lua:110 +}, -- ./candran/can-parser/parser.lua:110 +{ -- ./candran/can-parser/parser.lua:111 +"ErrInFor", -- ./candran/can-parser/parser.lua:111 +"expected '=' or 'in' after the variable(s)" -- ./candran/can-parser/parser.lua:111 +}, -- ./candran/can-parser/parser.lua:111 +{ -- ./candran/can-parser/parser.lua:112 +"ErrEListFor", -- ./candran/can-parser/parser.lua:112 +"expected one or more expressions after 'in'" -- ./candran/can-parser/parser.lua:112 +}, -- ./candran/can-parser/parser.lua:112 +{ -- ./candran/can-parser/parser.lua:113 +"ErrDoFor", -- ./candran/can-parser/parser.lua:113 +"expected 'do' after the range of the for loop" -- ./candran/can-parser/parser.lua:113 +}, -- ./candran/can-parser/parser.lua:113 +{ -- ./candran/can-parser/parser.lua:115 +"ErrDefLocal", -- ./candran/can-parser/parser.lua:115 +"expected a function definition or assignment after local" -- ./candran/can-parser/parser.lua:115 +}, -- ./candran/can-parser/parser.lua:115 +{ -- ./candran/can-parser/parser.lua:116 +"ErrDefLet", -- ./candran/can-parser/parser.lua:116 +"expected a function definition or assignment after let" -- ./candran/can-parser/parser.lua:116 +}, -- ./candran/can-parser/parser.lua:116 +{ -- ./candran/can-parser/parser.lua:117 +"ErrNameLFunc", -- ./candran/can-parser/parser.lua:117 +"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:117 +}, -- ./candran/can-parser/parser.lua:117 +{ -- ./candran/can-parser/parser.lua:118 +"ErrEListLAssign", -- ./candran/can-parser/parser.lua:118 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:118 +}, -- ./candran/can-parser/parser.lua:118 +{ -- ./candran/can-parser/parser.lua:119 +"ErrEListAssign", -- ./candran/can-parser/parser.lua:119 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:119 +}, -- ./candran/can-parser/parser.lua:119 +{ -- ./candran/can-parser/parser.lua:121 +"ErrFuncName", -- ./candran/can-parser/parser.lua:121 +"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:121 +}, -- ./candran/can-parser/parser.lua:121 +{ -- ./candran/can-parser/parser.lua:122 +"ErrNameFunc1", -- ./candran/can-parser/parser.lua:122 +"expected a function name after '.'" -- ./candran/can-parser/parser.lua:122 +}, -- ./candran/can-parser/parser.lua:122 +{ -- ./candran/can-parser/parser.lua:123 +"ErrNameFunc2", -- ./candran/can-parser/parser.lua:123 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:123 +}, -- ./candran/can-parser/parser.lua:123 +{ -- ./candran/can-parser/parser.lua:124 +"ErrOParenPList", -- ./candran/can-parser/parser.lua:124 +"expected '(' for the parameter list" -- ./candran/can-parser/parser.lua:124 +}, -- ./candran/can-parser/parser.lua:124 +{ -- ./candran/can-parser/parser.lua:125 +"ErrCParenPList", -- ./candran/can-parser/parser.lua:125 +"expected ')' to close the parameter list" -- ./candran/can-parser/parser.lua:125 +}, -- ./candran/can-parser/parser.lua:125 +{ -- ./candran/can-parser/parser.lua:126 +"ErrEndFunc", -- ./candran/can-parser/parser.lua:126 +"expected 'end' to close the function body" -- ./candran/can-parser/parser.lua:126 +}, -- ./candran/can-parser/parser.lua:126 +{ -- ./candran/can-parser/parser.lua:127 +"ErrParList", -- ./candran/can-parser/parser.lua:127 +"expected a variable name or '...' after ','" -- ./candran/can-parser/parser.lua:127 +}, -- ./candran/can-parser/parser.lua:127 +{ -- ./candran/can-parser/parser.lua:129 +"ErrLabel", -- ./candran/can-parser/parser.lua:129 +"expected a label name after '::'" -- ./candran/can-parser/parser.lua:129 +}, -- ./candran/can-parser/parser.lua:129 +{ -- ./candran/can-parser/parser.lua:130 +"ErrCloseLabel", -- ./candran/can-parser/parser.lua:130 +"expected '::' after the label" -- ./candran/can-parser/parser.lua:130 +}, -- ./candran/can-parser/parser.lua:130 +{ -- ./candran/can-parser/parser.lua:131 +"ErrGoto", -- ./candran/can-parser/parser.lua:131 +"expected a label after 'goto'" -- ./candran/can-parser/parser.lua:131 +}, -- ./candran/can-parser/parser.lua:131 +{ -- ./candran/can-parser/parser.lua:132 +"ErrRetList", -- ./candran/can-parser/parser.lua:132 +"expected an expression after ',' in the return statement" -- ./candran/can-parser/parser.lua:132 +}, -- ./candran/can-parser/parser.lua:132 +{ -- ./candran/can-parser/parser.lua:134 +"ErrVarList", -- ./candran/can-parser/parser.lua:134 +"expected a variable name after ','" -- ./candran/can-parser/parser.lua:134 +}, -- ./candran/can-parser/parser.lua:134 +{ -- ./candran/can-parser/parser.lua:135 +"ErrExprList", -- ./candran/can-parser/parser.lua:135 +"expected an expression after ','" -- ./candran/can-parser/parser.lua:135 +}, -- ./candran/can-parser/parser.lua:135 +{ -- ./candran/can-parser/parser.lua:137 +"ErrOrExpr", -- ./candran/can-parser/parser.lua:137 +"expected an expression after 'or'" -- ./candran/can-parser/parser.lua:137 +}, -- ./candran/can-parser/parser.lua:137 +{ -- ./candran/can-parser/parser.lua:138 +"ErrAndExpr", -- ./candran/can-parser/parser.lua:138 +"expected an expression after 'and'" -- ./candran/can-parser/parser.lua:138 +}, -- ./candran/can-parser/parser.lua:138 +{ -- ./candran/can-parser/parser.lua:139 +"ErrRelExpr", -- ./candran/can-parser/parser.lua:139 +"expected an expression after the relational operator" -- ./candran/can-parser/parser.lua:139 +}, -- ./candran/can-parser/parser.lua:139 +{ -- ./candran/can-parser/parser.lua:140 +"ErrBOrExpr", -- ./candran/can-parser/parser.lua:140 +"expected an expression after '|'" -- ./candran/can-parser/parser.lua:140 +}, -- ./candran/can-parser/parser.lua:140 +{ -- ./candran/can-parser/parser.lua:141 +"ErrBXorExpr", -- ./candran/can-parser/parser.lua:141 +"expected an expression after '~'" -- ./candran/can-parser/parser.lua:141 +}, -- ./candran/can-parser/parser.lua:141 +{ -- ./candran/can-parser/parser.lua:142 +"ErrBAndExpr", -- ./candran/can-parser/parser.lua:142 +"expected an expression after '&'" -- ./candran/can-parser/parser.lua:142 +}, -- ./candran/can-parser/parser.lua:142 +{ -- ./candran/can-parser/parser.lua:143 +"ErrShiftExpr", -- ./candran/can-parser/parser.lua:143 +"expected an expression after the bit shift" -- ./candran/can-parser/parser.lua:143 +}, -- ./candran/can-parser/parser.lua:143 +{ -- ./candran/can-parser/parser.lua:144 +"ErrConcatExpr", -- ./candran/can-parser/parser.lua:144 +"expected an expression after '..'" -- ./candran/can-parser/parser.lua:144 +}, -- ./candran/can-parser/parser.lua:144 +{ -- ./candran/can-parser/parser.lua:145 +"ErrAddExpr", -- ./candran/can-parser/parser.lua:145 +"expected an expression after the additive operator" -- ./candran/can-parser/parser.lua:145 +}, -- ./candran/can-parser/parser.lua:145 +{ -- ./candran/can-parser/parser.lua:146 +"ErrMulExpr", -- ./candran/can-parser/parser.lua:146 +"expected an expression after the multiplicative operator" -- ./candran/can-parser/parser.lua:146 +}, -- ./candran/can-parser/parser.lua:146 +{ -- ./candran/can-parser/parser.lua:147 +"ErrUnaryExpr", -- ./candran/can-parser/parser.lua:147 +"expected an expression after the unary operator" -- ./candran/can-parser/parser.lua:147 +}, -- ./candran/can-parser/parser.lua:147 +{ -- ./candran/can-parser/parser.lua:148 +"ErrPowExpr", -- ./candran/can-parser/parser.lua:148 +"expected an expression after '^'" -- ./candran/can-parser/parser.lua:148 +}, -- ./candran/can-parser/parser.lua:148 +{ -- ./candran/can-parser/parser.lua:150 +"ErrExprParen", -- ./candran/can-parser/parser.lua:150 +"expected an expression after '('" -- ./candran/can-parser/parser.lua:150 +}, -- ./candran/can-parser/parser.lua:150 +{ -- ./candran/can-parser/parser.lua:151 +"ErrCParenExpr", -- ./candran/can-parser/parser.lua:151 +"expected ')' to close the expression" -- ./candran/can-parser/parser.lua:151 +}, -- ./candran/can-parser/parser.lua:151 +{ -- ./candran/can-parser/parser.lua:152 +"ErrNameIndex", -- ./candran/can-parser/parser.lua:152 +"expected a field name after '.'" -- ./candran/can-parser/parser.lua:152 +}, -- ./candran/can-parser/parser.lua:152 +{ -- ./candran/can-parser/parser.lua:153 +"ErrExprIndex", -- ./candran/can-parser/parser.lua:153 +"expected an expression after '['" -- ./candran/can-parser/parser.lua:153 +}, -- ./candran/can-parser/parser.lua:153 +{ -- ./candran/can-parser/parser.lua:154 +"ErrCBracketIndex", -- ./candran/can-parser/parser.lua:154 +"expected ']' to close the indexing expression" -- ./candran/can-parser/parser.lua:154 +}, -- ./candran/can-parser/parser.lua:154 +{ -- ./candran/can-parser/parser.lua:155 +"ErrNameMeth", -- ./candran/can-parser/parser.lua:155 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:155 +}, -- ./candran/can-parser/parser.lua:155 +{ -- ./candran/can-parser/parser.lua:156 +"ErrMethArgs", -- ./candran/can-parser/parser.lua:156 +"expected some arguments for the method call (or '()')" -- ./candran/can-parser/parser.lua:156 +}, -- ./candran/can-parser/parser.lua:156 +{ -- ./candran/can-parser/parser.lua:158 +"ErrArgList", -- ./candran/can-parser/parser.lua:158 +"expected an expression after ',' in the argument list" -- ./candran/can-parser/parser.lua:158 +}, -- ./candran/can-parser/parser.lua:158 +{ -- ./candran/can-parser/parser.lua:159 +"ErrCParenArgs", -- ./candran/can-parser/parser.lua:159 +"expected ')' to close the argument list" -- ./candran/can-parser/parser.lua:159 +}, -- ./candran/can-parser/parser.lua:159 +{ -- ./candran/can-parser/parser.lua:161 +"ErrCBraceTable", -- ./candran/can-parser/parser.lua:161 +"expected '}' to close the table constructor" -- ./candran/can-parser/parser.lua:161 +}, -- ./candran/can-parser/parser.lua:161 +{ -- ./candran/can-parser/parser.lua:162 +"ErrEqField", -- ./candran/can-parser/parser.lua:162 +"expected '=' after the table key" -- ./candran/can-parser/parser.lua:162 +}, -- ./candran/can-parser/parser.lua:162 +{ -- ./candran/can-parser/parser.lua:163 +"ErrExprField", -- ./candran/can-parser/parser.lua:163 +"expected an expression after '='" -- ./candran/can-parser/parser.lua:163 +}, -- ./candran/can-parser/parser.lua:163 +{ -- ./candran/can-parser/parser.lua:164 +"ErrExprFKey", -- ./candran/can-parser/parser.lua:164 +"expected an expression after '[' for the table key" -- ./candran/can-parser/parser.lua:164 +}, -- ./candran/can-parser/parser.lua:164 +{ -- ./candran/can-parser/parser.lua:165 +"ErrCBracketFKey", -- ./candran/can-parser/parser.lua:165 +"expected ']' to close the table key" -- ./candran/can-parser/parser.lua:165 +}, -- ./candran/can-parser/parser.lua:165 +{ -- ./candran/can-parser/parser.lua:167 +"ErrCBraceDestructuring", -- ./candran/can-parser/parser.lua:167 +"expected '}' to close the destructuring variable list" -- ./candran/can-parser/parser.lua:167 +}, -- ./candran/can-parser/parser.lua:167 +{ -- ./candran/can-parser/parser.lua:168 +"ErrDestructuringEqField", -- ./candran/can-parser/parser.lua:168 +"expected '=' after the table key in destructuring variable list" -- ./candran/can-parser/parser.lua:168 +}, -- ./candran/can-parser/parser.lua:168 +{ -- ./candran/can-parser/parser.lua:169 +"ErrDestructuringExprField", -- ./candran/can-parser/parser.lua:169 +"expected an identifier after '=' in destructuring variable list" -- ./candran/can-parser/parser.lua:169 +}, -- ./candran/can-parser/parser.lua:169 +{ -- ./candran/can-parser/parser.lua:171 +"ErrCBracketTableCompr", -- ./candran/can-parser/parser.lua:171 +"expected ']' to close the table comprehension" -- ./candran/can-parser/parser.lua:171 +}, -- ./candran/can-parser/parser.lua:171 +{ -- ./candran/can-parser/parser.lua:173 +"ErrDigitHex", -- ./candran/can-parser/parser.lua:173 +"expected one or more hexadecimal digits after '0x'" -- ./candran/can-parser/parser.lua:173 +}, -- ./candran/can-parser/parser.lua:173 +{ -- ./candran/can-parser/parser.lua:174 +"ErrDigitDeci", -- ./candran/can-parser/parser.lua:174 +"expected one or more digits after the decimal point" -- ./candran/can-parser/parser.lua:174 +}, -- ./candran/can-parser/parser.lua:174 +{ -- ./candran/can-parser/parser.lua:175 +"ErrDigitExpo", -- ./candran/can-parser/parser.lua:175 +"expected one or more digits for the exponent" -- ./candran/can-parser/parser.lua:175 +}, -- ./candran/can-parser/parser.lua:175 +{ -- ./candran/can-parser/parser.lua:177 +"ErrQuote", -- ./candran/can-parser/parser.lua:177 +"unclosed string" -- ./candran/can-parser/parser.lua:177 +}, -- ./candran/can-parser/parser.lua:177 +{ -- ./candran/can-parser/parser.lua:178 +"ErrHexEsc", -- ./candran/can-parser/parser.lua:178 +"expected exactly two hexadecimal digits after '\\x'" -- ./candran/can-parser/parser.lua:178 +}, -- ./candran/can-parser/parser.lua:178 +{ -- ./candran/can-parser/parser.lua:179 +"ErrOBraceUEsc", -- ./candran/can-parser/parser.lua:179 +"expected '{' after '\\u'" -- ./candran/can-parser/parser.lua:179 +}, -- ./candran/can-parser/parser.lua:179 +{ -- ./candran/can-parser/parser.lua:180 +"ErrDigitUEsc", -- ./candran/can-parser/parser.lua:180 +"expected one or more hexadecimal digits for the UTF-8 code point" -- ./candran/can-parser/parser.lua:180 +}, -- ./candran/can-parser/parser.lua:180 +{ -- ./candran/can-parser/parser.lua:181 +"ErrCBraceUEsc", -- ./candran/can-parser/parser.lua:181 +"expected '}' after the code point" -- ./candran/can-parser/parser.lua:181 +}, -- ./candran/can-parser/parser.lua:181 +{ -- ./candran/can-parser/parser.lua:182 +"ErrEscSeq", -- ./candran/can-parser/parser.lua:182 +"invalid escape sequence" -- ./candran/can-parser/parser.lua:182 +}, -- ./candran/can-parser/parser.lua:182 +{ -- ./candran/can-parser/parser.lua:183 +"ErrCloseLStr", -- ./candran/can-parser/parser.lua:183 +"unclosed long string" -- ./candran/can-parser/parser.lua:183 +} -- ./candran/can-parser/parser.lua:183 +} -- ./candran/can-parser/parser.lua:183 +local function throw(label) -- ./candran/can-parser/parser.lua:186 +label = "Err" .. label -- ./candran/can-parser/parser.lua:187 +for i, labelinfo in ipairs(labels) do -- ./candran/can-parser/parser.lua:188 +if labelinfo[1] == label then -- ./candran/can-parser/parser.lua:189 +return T(i) -- ./candran/can-parser/parser.lua:190 +end -- ./candran/can-parser/parser.lua:190 +end -- ./candran/can-parser/parser.lua:190 +error("Label not found: " .. label) -- ./candran/can-parser/parser.lua:194 +end -- ./candran/can-parser/parser.lua:194 +local function expect(patt, label) -- ./candran/can-parser/parser.lua:197 +return patt + throw(label) -- ./candran/can-parser/parser.lua:198 +end -- ./candran/can-parser/parser.lua:198 +local function token(patt) -- ./candran/can-parser/parser.lua:204 +return patt * V("Skip") -- ./candran/can-parser/parser.lua:205 +end -- ./candran/can-parser/parser.lua:205 +local function sym(str) -- ./candran/can-parser/parser.lua:208 +return token(P(str)) -- ./candran/can-parser/parser.lua:209 +end -- ./candran/can-parser/parser.lua:209 +local function kw(str) -- ./candran/can-parser/parser.lua:212 +return token(P(str) * - V("IdRest")) -- ./candran/can-parser/parser.lua:213 +end -- ./candran/can-parser/parser.lua:213 +local function tagC(tag, patt) -- ./candran/can-parser/parser.lua:216 +return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./candran/can-parser/parser.lua:217 +end -- ./candran/can-parser/parser.lua:217 +local function unaryOp(op, e) -- ./candran/can-parser/parser.lua:220 +return { -- ./candran/can-parser/parser.lua:221 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:221 +["pos"] = e["pos"], -- ./candran/can-parser/parser.lua:221 +[1] = op, -- ./candran/can-parser/parser.lua:221 +[2] = e -- ./candran/can-parser/parser.lua:221 +} -- ./candran/can-parser/parser.lua:221 +end -- ./candran/can-parser/parser.lua:221 +local function binaryOp(e1, op, e2) -- ./candran/can-parser/parser.lua:224 +if not op then -- ./candran/can-parser/parser.lua:225 +return e1 -- ./candran/can-parser/parser.lua:226 +else -- ./candran/can-parser/parser.lua:226 +return { -- ./candran/can-parser/parser.lua:228 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:228 +["pos"] = e1["pos"], -- ./candran/can-parser/parser.lua:228 +[1] = op, -- ./candran/can-parser/parser.lua:228 +[2] = e1, -- ./candran/can-parser/parser.lua:228 +[3] = e2 -- ./candran/can-parser/parser.lua:228 +} -- ./candran/can-parser/parser.lua:228 +end -- ./candran/can-parser/parser.lua:228 +end -- ./candran/can-parser/parser.lua:228 +local function sepBy(patt, sep, label) -- ./candran/can-parser/parser.lua:232 +if label then -- ./candran/can-parser/parser.lua:233 +return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./candran/can-parser/parser.lua:234 +else -- ./candran/can-parser/parser.lua:234 +return patt * Cg(sep * patt) ^ 0 -- ./candran/can-parser/parser.lua:236 +end -- ./candran/can-parser/parser.lua:236 +end -- ./candran/can-parser/parser.lua:236 +local function chainOp(patt, sep, label) -- ./candran/can-parser/parser.lua:240 +return Cf(sepBy(patt, sep, label), binaryOp) -- ./candran/can-parser/parser.lua:241 +end -- ./candran/can-parser/parser.lua:241 +local function commaSep(patt, label) -- ./candran/can-parser/parser.lua:244 +return sepBy(patt, sym(","), label) -- ./candran/can-parser/parser.lua:245 +end -- ./candran/can-parser/parser.lua:245 +local function tagDo(block) -- ./candran/can-parser/parser.lua:248 +block["tag"] = "Do" -- ./candran/can-parser/parser.lua:249 +return block -- ./candran/can-parser/parser.lua:250 +end -- ./candran/can-parser/parser.lua:250 +local function fixFuncStat(func) -- ./candran/can-parser/parser.lua:253 +if func[1]["is_method"] then -- ./candran/can-parser/parser.lua:254 +table["insert"](func[2][1], 1, { -- ./candran/can-parser/parser.lua:254 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:254 +[1] = "self" -- ./candran/can-parser/parser.lua:254 +}) -- ./candran/can-parser/parser.lua:254 +end -- ./candran/can-parser/parser.lua:254 +func[1] = { func[1] } -- ./candran/can-parser/parser.lua:255 +func[2] = { func[2] } -- ./candran/can-parser/parser.lua:256 +return func -- ./candran/can-parser/parser.lua:257 +end -- ./candran/can-parser/parser.lua:257 +local function addDots(params, dots) -- ./candran/can-parser/parser.lua:260 +if dots then -- ./candran/can-parser/parser.lua:261 +table["insert"](params, dots) -- ./candran/can-parser/parser.lua:261 +end -- ./candran/can-parser/parser.lua:261 +return params -- ./candran/can-parser/parser.lua:262 +end -- ./candran/can-parser/parser.lua:262 +local function insertIndex(t, index) -- ./candran/can-parser/parser.lua:265 +return { -- ./candran/can-parser/parser.lua:266 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:266 +["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:266 +[1] = t, -- ./candran/can-parser/parser.lua:266 +[2] = index -- ./candran/can-parser/parser.lua:266 +} -- ./candran/can-parser/parser.lua:266 +end -- ./candran/can-parser/parser.lua:266 +local function markMethod(t, method) -- ./candran/can-parser/parser.lua:269 +if method then -- ./candran/can-parser/parser.lua:270 +return { -- ./candran/can-parser/parser.lua:271 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:271 +["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:271 +["is_method"] = true, -- ./candran/can-parser/parser.lua:271 +[1] = t, -- ./candran/can-parser/parser.lua:271 +[2] = method -- ./candran/can-parser/parser.lua:271 +} -- ./candran/can-parser/parser.lua:271 +end -- ./candran/can-parser/parser.lua:271 +return t -- ./candran/can-parser/parser.lua:273 +end -- ./candran/can-parser/parser.lua:273 +local function makeSuffixedExpr(t1, t2) -- ./candran/can-parser/parser.lua:276 +if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./candran/can-parser/parser.lua:277 +local t = { -- ./candran/can-parser/parser.lua:278 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:278 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:278 +[1] = t1 -- ./candran/can-parser/parser.lua:278 +} -- ./candran/can-parser/parser.lua:278 +for k, v in ipairs(t2) do -- ./candran/can-parser/parser.lua:279 +table["insert"](t, v) -- ./candran/can-parser/parser.lua:280 +end -- ./candran/can-parser/parser.lua:280 +return t -- ./candran/can-parser/parser.lua:282 +elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./candran/can-parser/parser.lua:283 +return { -- ./candran/can-parser/parser.lua:284 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:284 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:284 +[1] = t1, -- ./candran/can-parser/parser.lua:284 +[2] = t2[1] -- ./candran/can-parser/parser.lua:284 +} -- ./candran/can-parser/parser.lua:284 +elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./candran/can-parser/parser.lua:285 +return { -- ./candran/can-parser/parser.lua:286 +["tag"] = "SafeIndex", -- ./candran/can-parser/parser.lua:286 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:286 +[1] = t1, -- ./candran/can-parser/parser.lua:286 +[2] = t2[1] -- ./candran/can-parser/parser.lua:286 +} -- ./candran/can-parser/parser.lua:286 +elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./candran/can-parser/parser.lua:287 +return { -- ./candran/can-parser/parser.lua:288 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:288 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:288 +[1] = t1, -- ./candran/can-parser/parser.lua:288 +[2] = t2[1] -- ./candran/can-parser/parser.lua:288 +} -- ./candran/can-parser/parser.lua:288 +else -- ./candran/can-parser/parser.lua:288 +error("unexpected tag in suffixed expression") -- ./candran/can-parser/parser.lua:290 +end -- ./candran/can-parser/parser.lua:290 +end -- ./candran/can-parser/parser.lua:290 +local function fixShortFunc(t) -- ./candran/can-parser/parser.lua:294 +if t[1] == ":" then -- ./candran/can-parser/parser.lua:295 +table["insert"](t[2], 1, { -- ./candran/can-parser/parser.lua:296 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:296 +"self" -- ./candran/can-parser/parser.lua:296 +}) -- ./candran/can-parser/parser.lua:296 +table["remove"](t, 1) -- ./candran/can-parser/parser.lua:297 +t["is_method"] = true -- ./candran/can-parser/parser.lua:298 +end -- ./candran/can-parser/parser.lua:298 +t["is_short"] = true -- ./candran/can-parser/parser.lua:300 +return t -- ./candran/can-parser/parser.lua:301 +end -- ./candran/can-parser/parser.lua:301 +local function statToExpr(t) -- ./candran/can-parser/parser.lua:304 +t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:305 +return t -- ./candran/can-parser/parser.lua:306 +end -- ./candran/can-parser/parser.lua:306 +local function fixStructure(t) -- ./candran/can-parser/parser.lua:309 +local i = 1 -- ./candran/can-parser/parser.lua:310 +while i <= # t do -- ./candran/can-parser/parser.lua:311 +if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:312 +fixStructure(t[i]) -- ./candran/can-parser/parser.lua:313 +for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:314 +local stat = t[i][j] -- ./candran/can-parser/parser.lua:315 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:316 +table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:317 +table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:318 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:319 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:320 +end -- ./candran/can-parser/parser.lua:320 +end -- ./candran/can-parser/parser.lua:320 +end -- ./candran/can-parser/parser.lua:320 +end -- ./candran/can-parser/parser.lua:320 +i = i + 1 -- ./candran/can-parser/parser.lua:325 +end -- ./candran/can-parser/parser.lua:325 +return t -- ./candran/can-parser/parser.lua:327 +end -- ./candran/can-parser/parser.lua:327 +local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:330 +for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:331 +if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:333 +local exprlist -- ./candran/can-parser/parser.lua:334 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:336 +exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:337 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:338 +exprlist = stat -- ./candran/can-parser/parser.lua:339 +end -- ./candran/can-parser/parser.lua:339 +local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:342 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:346 +local p = i -- ./candran/can-parser/parser.lua:347 +for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:348 +p = i + j -- ./candran/can-parser/parser.lua:349 +table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:350 +if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:352 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:353 +end -- ./candran/can-parser/parser.lua:353 +if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:356 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:357 +end -- ./candran/can-parser/parser.lua:357 +end -- ./candran/can-parser/parser.lua:357 +exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:361 +exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:362 +if not isRecCall then -- ./candran/can-parser/parser.lua:364 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:365 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:366 +end -- ./candran/can-parser/parser.lua:366 +end -- ./candran/can-parser/parser.lua:366 +return block, i -- ./candran/can-parser/parser.lua:370 +elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:373 +local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:374 +if r then -- ./candran/can-parser/parser.lua:375 +for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:376 +table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:377 +end -- ./candran/can-parser/parser.lua:377 +return block, i -- ./candran/can-parser/parser.lua:379 +end -- ./candran/can-parser/parser.lua:379 +elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:381 +local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:382 +if r then -- ./candran/can-parser/parser.lua:383 +return block, i -- ./candran/can-parser/parser.lua:384 +end -- ./candran/can-parser/parser.lua:384 +end -- ./candran/can-parser/parser.lua:384 +elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:389 +local blocks -- ./candran/can-parser/parser.lua:390 +if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:392 +blocks = stat -- ./candran/can-parser/parser.lua:393 +elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:394 +blocks = { stat } -- ./candran/can-parser/parser.lua:395 +end -- ./candran/can-parser/parser.lua:395 +for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:398 +if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:399 +local oldLen = # iblock -- ./candran/can-parser/parser.lua:400 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:401 +if newiBlock then -- ./candran/can-parser/parser.lua:402 +local p = i -- ./candran/can-parser/parser.lua:403 +for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:404 +p = p + 1 -- ./candran/can-parser/parser.lua:405 +table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:406 +iblock[j] = nil -- ./candran/can-parser/parser.lua:407 +end -- ./candran/can-parser/parser.lua:407 +if not isRecCall then -- ./candran/can-parser/parser.lua:410 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:411 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:412 +end -- ./candran/can-parser/parser.lua:412 +end -- ./candran/can-parser/parser.lua:412 +return block, i -- ./candran/can-parser/parser.lua:416 +end -- ./candran/can-parser/parser.lua:416 +end -- ./candran/can-parser/parser.lua:416 +end -- ./candran/can-parser/parser.lua:416 +end -- ./candran/can-parser/parser.lua:416 +end -- ./candran/can-parser/parser.lua:416 +return nil -- ./candran/can-parser/parser.lua:422 +end -- ./candran/can-parser/parser.lua:422 +local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:425 +local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:426 +if not r then -- ./candran/can-parser/parser.lua:427 +return false -- ./candran/can-parser/parser.lua:428 +end -- ./candran/can-parser/parser.lua:428 +return true, r -- ./candran/can-parser/parser.lua:430 +end -- ./candran/can-parser/parser.lua:430 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:433 +if canFollow then -- ./candran/can-parser/parser.lua:434 +return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:437 +else -- ./candran/can-parser/parser.lua:437 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:441 +end -- ./candran/can-parser/parser.lua:441 +end -- ./candran/can-parser/parser.lua:441 +local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:445 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:447 +end -- ./candran/can-parser/parser.lua:447 +local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:450 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:452 +end -- ./candran/can-parser/parser.lua:452 +local function maybe(patt) -- ./candran/can-parser/parser.lua:455 +return # patt / 0 * patt -- ./candran/can-parser/parser.lua:456 +end -- ./candran/can-parser/parser.lua:456 +local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:460 +local function push(f) -- ./candran/can-parser/parser.lua:462 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:463 +table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:464 +return true -- ./candran/can-parser/parser.lua:465 +end) -- ./candran/can-parser/parser.lua:465 +end -- ./candran/can-parser/parser.lua:465 +local function pop(f) -- ./candran/can-parser/parser.lua:468 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:469 +table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:470 +return true -- ./candran/can-parser/parser.lua:471 +end) -- ./candran/can-parser/parser.lua:471 +end -- ./candran/can-parser/parser.lua:471 +local function when(f) -- ./candran/can-parser/parser.lua:474 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:475 +return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:476 +end) -- ./candran/can-parser/parser.lua:476 +end -- ./candran/can-parser/parser.lua:476 +local function set(f, patt) -- ./candran/can-parser/parser.lua:479 +return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:480 +end -- ./candran/can-parser/parser.lua:480 +local G = { -- ./candran/can-parser/parser.lua:484 +V("Lua"), -- ./candran/can-parser/parser.lua:484 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:485 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 0, -- ./lib/lua-parser/parser.lua:482 -["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./lib/lua-parser/parser.lua:484 -["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./lib/lua-parser/parser.lua:490 -["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./lib/lua-parser/parser.lua:491 -["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./lib/lua-parser/parser.lua:493 -t["is_singlestatblock"] = true -- ./lib/lua-parser/parser.lua:493 -return t -- ./lib/lua-parser/parser.lua:493 -end, -- ./lib/lua-parser/parser.lua:493 -["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:494 -["IfStat"] = tagC("If", V("IfPart")), -- ./lib/lua-parser/parser.lua:496 -["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:497 -["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./lib/lua-parser/parser.lua:498 -["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./lib/lua-parser/parser.lua:499 -["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./lib/lua-parser/parser.lua:501 -["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./lib/lua-parser/parser.lua:502 -["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./lib/lua-parser/parser.lua:503 -["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./lib/lua-parser/parser.lua:504 -["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./lib/lua-parser/parser.lua:506 -["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./lib/lua-parser/parser.lua:507 -["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./lib/lua-parser/parser.lua:509 -["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./lib/lua-parser/parser.lua:510 -["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./lib/lua-parser/parser.lua:511 -["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./lib/lua-parser/parser.lua:513 -["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:514 -["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./lib/lua-parser/parser.lua:516 -["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./lib/lua-parser/parser.lua:518 -["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./lib/lua-parser/parser.lua:520 -["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./lib/lua-parser/parser.lua:522 -["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./lib/lua-parser/parser.lua:524 -["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./lib/lua-parser/parser.lua:526 -["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./lib/lua-parser/parser.lua:527 -["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./lib/lua-parser/parser.lua:528 -["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:531 -["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./lib/lua-parser/parser.lua:533 -["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./lib/lua-parser/parser.lua:534 -["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./lib/lua-parser/parser.lua:536 -["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:538 -["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:539 -["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./lib/lua-parser/parser.lua:541 -["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./lib/lua-parser/parser.lua:542 -["BreakStat"] = tagC("Break", kw("break")), -- ./lib/lua-parser/parser.lua:543 -["ContinueStat"] = tagC("Continue", kw("continue")), -- ./lib/lua-parser/parser.lua:544 -["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:545 -["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./lib/lua-parser/parser.lua:547 -["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./lib/lua-parser/parser.lua:548 -["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./lib/lua-parser/parser.lua:550 -["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./lib/lua-parser/parser.lua:551 -["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./lib/lua-parser/parser.lua:552 -["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./lib/lua-parser/parser.lua:553 -["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./lib/lua-parser/parser.lua:555 -["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:556 -["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./lib/lua-parser/parser.lua:558 -["Expr"] = V("OrExpr"), -- ./lib/lua-parser/parser.lua:560 -["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./lib/lua-parser/parser.lua:561 -["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./lib/lua-parser/parser.lua:562 -["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./lib/lua-parser/parser.lua:563 -["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./lib/lua-parser/parser.lua:564 -["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./lib/lua-parser/parser.lua:565 -["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./lib/lua-parser/parser.lua:566 -["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./lib/lua-parser/parser.lua:567 -["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:568 -["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./lib/lua-parser/parser.lua:569 -["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./lib/lua-parser/parser.lua:570 -["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./lib/lua-parser/parser.lua:572 -["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./lib/lua-parser/parser.lua:573 -["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("DestructuringNameList") * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./lib/lua-parser/parser.lua:583 -["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./lib/lua-parser/parser.lua:585 -["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:587 -return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./lib/lua-parser/parser.lua:587 -end), -- ./lib/lua-parser/parser.lua:587 -["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./lib/lua-parser/parser.lua:588 -return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./lib/lua-parser/parser.lua:588 -end), -- ./lib/lua-parser/parser.lua:588 -["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:592 -["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./lib/lua-parser/parser.lua:595 -["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./lib/lua-parser/parser.lua:596 -["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:600 -["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./lib/lua-parser/parser.lua:602 -["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./lib/lua-parser/parser.lua:604 -["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./lib/lua-parser/parser.lua:605 -["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./lib/lua-parser/parser.lua:606 -["FuncDef"] = (kw("function") * V("FuncBody")), -- ./lib/lua-parser/parser.lua:608 -["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./lib/lua-parser/parser.lua:611 -["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./lib/lua-parser/parser.lua:613 -["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./lib/lua-parser/parser.lua:614 -["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./lib/lua-parser/parser.lua:616 -["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./lib/lua-parser/parser.lua:618 -["FieldSep"] = sym(",") + sym(";"), -- ./lib/lua-parser/parser.lua:619 -["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./lib/lua-parser/parser.lua:621 -["SelfId"] = tagC("Id", sym("@") / "self"), -- ./lib/lua-parser/parser.lua:623 -["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./lib/lua-parser/parser.lua:624 -["StrId"] = tagC("String", V("Name")), -- ./lib/lua-parser/parser.lua:625 -["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./lib/lua-parser/parser.lua:628 -["Space"] = space ^ 1, -- ./lib/lua-parser/parser.lua:629 -["Comment"] = P("--") * V("LongStr") / function() -- ./lib/lua-parser/parser.lua:630 -return -- ./lib/lua-parser/parser.lua:630 +")) ^ 0, -- ./candran/can-parser/parser.lua:486 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:488 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:494 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:495 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:497 +t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:497 +return t -- ./candran/can-parser/parser.lua:497 +end, -- ./candran/can-parser/parser.lua:497 +["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:498 +["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:500 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:501 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:502 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:503 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:505 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:506 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:507 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:508 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:510 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:511 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:513 +["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:514 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:515 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:517 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:518 +["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:520 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:522 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:524 +["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:526 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:528 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:530 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:531 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:532 +["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:535 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:537 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:538 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:540 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:542 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:543 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:545 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:546 +["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:547 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:548 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:549 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:551 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./candran/can-parser/parser.lua:552 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:554 +["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:555 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:556 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:557 +["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:559 +["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:560 +["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:562 +["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:564 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:565 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:566 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:567 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:568 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:569 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:570 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:571 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:572 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:573 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:574 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:576 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:577 +["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:587 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:589 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:591 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:591 +end), -- ./candran/can-parser/parser.lua:591 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:592 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:592 +end), -- ./candran/can-parser/parser.lua:592 +["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:596 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:599 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:600 +["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:604 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:606 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:608 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:609 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:610 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:612 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:615 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:617 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:618 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:620 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:622 +["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:623 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:625 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:627 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:628 +["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:629 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:632 +["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:633 +["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:634 +return -- ./candran/can-parser/parser.lua:634 end + P("--") * (P(1) - P("\ -")) ^ 0, -- ./lib/lua-parser/parser.lua:631 -["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./lib/lua-parser/parser.lua:633 -["Reserved"] = V("Keywords") * - V("IdRest"), -- ./lib/lua-parser/parser.lua:634 -["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:638 -["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./lib/lua-parser/parser.lua:639 -["IdStart"] = alpha + P("_"), -- ./lib/lua-parser/parser.lua:640 -["IdRest"] = alnum + P("_"), -- ./lib/lua-parser/parser.lua:641 -["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./lib/lua-parser/parser.lua:643 -["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./lib/lua-parser/parser.lua:644 -["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./lib/lua-parser/parser.lua:646 -["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./lib/lua-parser/parser.lua:648 -["DeciHex"] = P(".") * xdigit ^ 0, -- ./lib/lua-parser/parser.lua:649 -["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:650 -["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./lib/lua-parser/parser.lua:651 -["Int"] = digit ^ 1, -- ./lib/lua-parser/parser.lua:652 -["String"] = token(V("ShortStr") + V("LongStr")), -- ./lib/lua-parser/parser.lua:654 +")) ^ 0, -- ./candran/can-parser/parser.lua:635 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:637 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:638 +["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:642 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:643 +["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:644 +["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:645 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:647 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:648 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:650 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:652 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:653 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:654 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:655 +["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:656 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:658 ["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:656 +"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:660 ["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:686 -["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./lib/lua-parser/parser.lua:689 -return s -- ./lib/lua-parser/parser.lua:689 -end, -- ./lib/lua-parser/parser.lua:689 +" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:690 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:693 +return s -- ./candran/can-parser/parser.lua:693 +end, -- ./candran/can-parser/parser.lua:693 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 1, -- ./lib/lua-parser/parser.lua:690 -["Close"] = "]" * C(V("Equals")) * "]", -- ./lib/lua-parser/parser.lua:691 -["Equals"] = P("=") ^ 0, -- ./lib/lua-parser/parser.lua:692 -["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./lib/lua-parser/parser.lua:693 -return # openEq == # closeEq -- ./lib/lua-parser/parser.lua:693 -end), -- ./lib/lua-parser/parser.lua:693 -["OrOp"] = kw("or") / "or", -- ./lib/lua-parser/parser.lua:695 -["AndOp"] = kw("and") / "and", -- ./lib/lua-parser/parser.lua:696 -["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./lib/lua-parser/parser.lua:702 -["BOrOp"] = sym("|") / "bor", -- ./lib/lua-parser/parser.lua:703 -["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./lib/lua-parser/parser.lua:704 -["BAndOp"] = sym("&") / "band", -- ./lib/lua-parser/parser.lua:705 -["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./lib/lua-parser/parser.lua:707 -["ConcatOp"] = sym("..") / "concat", -- ./lib/lua-parser/parser.lua:708 -["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./lib/lua-parser/parser.lua:710 -["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./lib/lua-parser/parser.lua:714 -["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./lib/lua-parser/parser.lua:718 -["PowOp"] = sym("^") / "pow", -- ./lib/lua-parser/parser.lua:719 -["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:720 -} -- ./lib/lua-parser/parser.lua:720 -local parser = {} -- ./lib/lua-parser/parser.lua:723 -local validator = require("lib.lua-parser.validator") -- ./lib/lua-parser/parser.lua:725 -local validate = validator["validate"] -- ./lib/lua-parser/parser.lua:726 -local syntaxerror = validator["syntaxerror"] -- ./lib/lua-parser/parser.lua:727 -parser["parse"] = function(subject, filename) -- ./lib/lua-parser/parser.lua:729 -local errorinfo = { -- ./lib/lua-parser/parser.lua:730 -["subject"] = subject, -- ./lib/lua-parser/parser.lua:730 -["filename"] = filename -- ./lib/lua-parser/parser.lua:730 -} -- ./lib/lua-parser/parser.lua:730 -lpeg["setmaxstack"](1000) -- ./lib/lua-parser/parser.lua:731 -local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./lib/lua-parser/parser.lua:732 -if not ast then -- ./lib/lua-parser/parser.lua:733 -local errmsg = labels[label][2] -- ./lib/lua-parser/parser.lua:734 -return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./lib/lua-parser/parser.lua:735 -end -- ./lib/lua-parser/parser.lua:735 -return validate(ast, errorinfo) -- ./lib/lua-parser/parser.lua:737 -end -- ./lib/lua-parser/parser.lua:737 -return parser -- ./lib/lua-parser/parser.lua:740 -end -- ./lib/lua-parser/parser.lua:740 -local parser = _() or parser -- ./lib/lua-parser/parser.lua:744 -package["loaded"]["lib.lua-parser.parser"] = parser or true -- ./lib/lua-parser/parser.lua:745 +") ^ - 1, -- ./candran/can-parser/parser.lua:694 +["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:695 +["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:696 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:697 +return # openEq == # closeEq -- ./candran/can-parser/parser.lua:697 +end), -- ./candran/can-parser/parser.lua:697 +["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:699 +["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:700 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:706 +["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:707 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:708 +["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:709 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:711 +["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:712 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:714 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:718 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:722 +["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:723 +["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:724 +} -- ./candran/can-parser/parser.lua:724 +local parser = {} -- ./candran/can-parser/parser.lua:727 +local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:729 +local validate = validator["validate"] -- ./candran/can-parser/parser.lua:730 +local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:731 +parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:733 +local errorinfo = { -- ./candran/can-parser/parser.lua:734 +["subject"] = subject, -- ./candran/can-parser/parser.lua:734 +["filename"] = filename -- ./candran/can-parser/parser.lua:734 +} -- ./candran/can-parser/parser.lua:734 +lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:735 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:736 +if not ast then -- ./candran/can-parser/parser.lua:737 +local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:738 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:739 +end -- ./candran/can-parser/parser.lua:739 +return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:741 +end -- ./candran/can-parser/parser.lua:741 +return parser -- ./candran/can-parser/parser.lua:744 +end -- ./candran/can-parser/parser.lua:744 +local parser = _() or parser -- ./candran/can-parser/parser.lua:748 +package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:749 local candran = { ["VERSION"] = "0.11.0" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 @@ -4522,7 +4525,7 @@ elseif line:match("%-%-%[%[") then -- candran.can:59 inComment = true -- candran.can:60 end -- candran.can:60 end -- candran.can:60 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- exclude shebang -- candran.can:63 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:63 preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:64 else -- candran.can:64 local l = line:sub(1, - 2) -- candran.can:66 diff --git a/lib/lua-parser/LICENSE b/candran/can-parser/LICENSE similarity index 100% rename from lib/lua-parser/LICENSE rename to candran/can-parser/LICENSE diff --git a/lib/lua-parser/README.md b/candran/can-parser/README.md similarity index 100% rename from lib/lua-parser/README.md rename to candran/can-parser/README.md diff --git a/lib/lua-parser/parser.lua b/candran/can-parser/parser.lua similarity index 98% rename from lib/lua-parser/parser.lua rename to candran/can-parser/parser.lua index 8864daa..0d17122 100644 --- a/lib/lua-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -9,7 +9,7 @@ block: { stat* } stat: `Do{ stat* } | `Set{ {lhs+} (opid? = opid?)? {expr+} } -- lhs1, lhs2... op=op e1, e2... - | `While{ expr block } -- while e do b end + | `While{ lexpr block } -- while e do b end | `Repeat{ block expr } -- repeat b until e | `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 @@ -452,6 +452,10 @@ local function maybeBlockWithEnd () -- same as above but don't error if it doesn + Cmt(V"BlockNoErr", searchEnd) end +local function maybe (patt) -- fail pattern instead of propagating errors + return #patt/0 * patt +end + local stacks = { lexpr = {} } @@ -577,7 +581,7 @@ local G = { V"Lua", + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V"FuncDef" - + (when("lexpr") * tagC("LetExpr", V"DestructuringNameList" * sym("=") * -sym("=") * expect(V"ExprList", "EListLAssign"))) + + (when("lexpr") * tagC("LetExpr", maybe(V"DestructuringNameList") * sym("=") * -sym("=") * expect(V"ExprList", "EListLAssign"))) + V"ShortFuncDef" + V"SuffixedExpr" + V"StatExpr"; @@ -722,7 +726,7 @@ local G = { V"Lua", local parser = {} -local validator = require("lib.lua-parser.validator") +local validator = require("candran.can-parser.validator") local validate = validator.validate local syntaxerror = validator.syntaxerror diff --git a/lib/lua-parser/pp.lua b/candran/can-parser/pp.lua similarity index 100% rename from lib/lua-parser/pp.lua rename to candran/can-parser/pp.lua diff --git a/lib/lua-parser/scope.lua b/candran/can-parser/scope.lua similarity index 100% rename from lib/lua-parser/scope.lua rename to candran/can-parser/scope.lua diff --git a/lib/lua-parser/validator.lua b/candran/can-parser/validator.lua similarity index 99% rename from lib/lua-parser/validator.lua rename to candran/can-parser/validator.lua index 210cc82..ec15a63 100644 --- a/lib/lua-parser/validator.lua +++ b/candran/can-parser/validator.lua @@ -1,7 +1,7 @@ --[[ This module impements a validator for the AST ]] -local scope = require "lib.lua-parser.scope" +local scope = require "candran.can-parser.scope" local lineno = scope.lineno local new_scope, end_scope = scope.new_scope, scope.end_scope diff --git a/lib/cmdline.lua b/candran/cmdline.lua similarity index 100% rename from lib/cmdline.lua rename to candran/cmdline.lua diff --git a/lib/util.can b/candran/util.can similarity index 100% rename from lib/util.can rename to candran/util.can diff --git a/test/test.lua b/test/test.lua index b43603c..1588ab0 100644 --- a/test/test.lua +++ b/test/test.lua @@ -2,7 +2,7 @@ local candran = dofile(arg[1] or "../candran.lua") candran.default.indentation = "\t" candran.default.mapLines = false -local load = require("lib.util").load +local load = require("candran.util").load -- test helper local results = {} -- tests result From 1de0aafa5bd0a96c6a40de33e130bf7413fa539f Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 6 Apr 2020 21:30:57 +0200 Subject: [PATCH 10/52] Added cancheck; candran.compile, .make and .preprocess returns nil, err instead of throwing an error; can and canc error output should now be similar to Lua --- bin/can | 11 +- bin/canc | 24 +- bin/cancheck | 116 +++++++++ candran.can | 63 +++-- candran.lua | 412 +++++++++++++++++--------------- compiler/lua53.can | 2 +- compiler/luajit.can | 2 +- rockspec/candran-scm-1.rockspec | 6 +- test/test.lua | 2 +- 9 files changed, 412 insertions(+), 226 deletions(-) create mode 100644 bin/cancheck diff --git a/bin/can b/bin/can index 2ec98fd..9076123 100644 --- a/bin/can +++ b/bin/can @@ -1,4 +1,5 @@ -#!/bin/lua +#!/usr/bin/env lua + local candran = require("candran") local cmdline = require("candran.cmdline") @@ -29,7 +30,13 @@ if arg[#arg] == "-" then f() -- file elseif #args >= 1 then - candran.dofile(args[1], args) + local f, err = candran.loadfile(args[1], nil, args) + if not f then + print("can: "..err) + os.exit(1) + else + f() + end -- REPL else -- Setup linenoise diff --git a/bin/canc b/bin/canc index d6fbb6c..c73d368 100644 --- a/bin/canc +++ b/bin/canc @@ -1,4 +1,5 @@ -#!/bin/lua +#!/usr/bin/env lua + local candran = require("candran") local cmdline = require("candran.cmdline") local parse = require("candran.can-parser.parser").parse @@ -78,13 +79,28 @@ for _, file in ipairs(args) do local out = input if args.preprocess then - out = candran.preprocess(out, args) + local r, err = candran.preprocess(out, args) + if not r then + print("canc: "..err) + os.exit(1) + end + out = r end if args.compile then - out = candran.compile(out, args) + local r, err = candran.compile(out, args) + if not r then + print("canc: "..err) + os.exit(1) + end + out = r end if args.compile == nil and args.preprocess == nil then - out = candran.make(input, args) + local r, err = candran.make(input, args) + if not r then + print("canc: "..err) + os.exit(1) + end + out = r end if args.print then diff --git a/bin/cancheck b/bin/cancheck new file mode 100644 index 0000000..df59191 --- /dev/null +++ b/bin/cancheck @@ -0,0 +1,116 @@ +#!/usr/bin/env lua + +-- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files +local candran = require("candran") + +local function pattern(token) + return "()"..token:gsub("[^%w]", "%%%0").."()" +end + +local tokenAlias = { + ["self"] = { "@", ":" } +} + +-- Patch checker +local oldCheck = require("luacheck.check") +local function check(can) + local lua, err = candran.make(can) + if lua then + local r = oldCheck(lua) + -- Calculate Candran file position. + if #r.warnings > 0 then + local lua_lines = {} + for l in (lua.."\n"):gmatch("([^\n]*)\n") do + table.insert(lua_lines, l) + end + local can_lines = {} + for l in (can.."\n"):gmatch("([^\n]*)\n") do + table.insert(can_lines, l) + end + for _, warning in ipairs(r.warnings) do + -- candran line + local lua_line = lua_lines[warning.line] + warning.can_line = tonumber(lua_line:match(".*%-%- .-%:(%d+)$")) + + -- candran column + local can_line = can_lines[warning.can_line] + local lua_token = lua_line:sub(warning.column, warning.end_column) + local token_pattern = pattern(lua_token) -- token finding pattern + -- the warning happens on the n-th instance of lua_token on this line + local lua_n = 1 + for start in lua_line:gmatch(token_pattern) do + if start >= warning.column then + break + end + lua_n = lua_n + 1 + end + -- Find associated candran token. If lua_n > can_nmax, the last found lua_token is used. + -- This approximation should work in like, 90% of cases. + local can_n = 1 + local pos = 1 + while can_n <= lua_n do + -- find first token or alias of this token + local start, stop = can_line:match(token_pattern, pos) + if tokenAlias[lua_token] then + for _, token in ipairs(tokenAlias[lua_token]) do + local nstart, nstop = can_line:match(pattern(token), pos) + if nstart and (not start or nstart < start) then + start, stop = nstart, nstop + end + end + end + -- found + if start then + pos = stop + warning.can_column, warning.can_end_column = start, stop + can_n = can_n + 1 + else + break + end + end + end + end + return r + else + local line, column, msg = err:match(":(%d+):(%d+):%s*(.*)$") + local syntax_error = { + code = "011", + line = line, + column = column, + end_column = column, + msg = msg + } + return { + warnings = {syntax_error}, + inline_options = {}, + line_lengths = {}, + line_endings = {} + } + end +end +package.loaded["luacheck.check"] = check + +-- Patch formatter +local format = require("luacheck.format") +local function format_location(file, location, opts) + local res = ("%s:%d:%d"):format(file, location.can_line or location.line, location.can_column or location.column) + if opts.ranges then + res = ("%s-%d"):format(res, location.can_end_column or location.end_column) + end + return res +end +local function setupvalue(fn, val, name, ...) + for i=1, debug.getinfo(fn, "u").nups do + local n, v = debug.getupvalue(fn, i) + if n == name then + if not ... then + debug.setupvalue(fn, i, val) + else + setupvalue(v, val, ...) + end + end + end +end +setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location") + +require("luacheck.main") diff --git a/candran.can b/candran.can index 3bbed3b..2022852 100644 --- a/candran.can +++ b/candran.can @@ -11,7 +11,7 @@ #import("candran.can-parser.parser") local candran = { - VERSION = "0.11.0" + VERSION = "0.12.0" } --- Default options. @@ -37,7 +37,9 @@ end --- Run the preprocessor -- @tparam input string input code -- @tparam options table arguments for the preprocessor. They will be inserted into the preprocessor environement. --- @treturn output string output code +-- @treturn[1] output string output code +-- @treturn[2] nil nil if error +-- @treturn[2] error string error message function candran.preprocess(input, options={}) options = util.merge(candran.default, options) @@ -90,10 +92,10 @@ function candran.preprocess(input, options={}) -- open module file local f = io.open(filepath) - if not f then error("Can't open the module file to import") end + if not f then error("can't open the module file to import") end margs = util.merge(options, { chunkname = filepath, loadLocal = true, loadPackage = true }, margs) - local modcontent = candran.preprocess(f:read("*a"), margs) + local modcontent = assert(candran.preprocess(f:read("*a"), margs)) f:close() -- get module name (ex: module name of path.to.module is module) @@ -113,7 +115,7 @@ function candran.preprocess(input, options={}) -- @tparam file string filepath env.include = function(file) local f = io.open(file) - if not f then error("Can't open the file "..file.." to include") end + if not f then error("can't open the file "..file.." to include") end env.write(f:read("*a")) f:close() end @@ -131,12 +133,21 @@ function candran.preprocess(input, options={}) end -- compile & load preprocessor - local preprocess, err = util.load(candran.compile(preprocessor, args), "candran preprocessor", env) - if not preprocess then error("Error while creating Candran preprocessor: " .. err) end + local preprocess, err = candran.compile(preprocessor, options) + if not preprocess then + return nil, "in preprocessor: "..err + end + + preprocess, err = util.load(preprocessor, "candran preprocessor", env) + if not preprocess then + return nil, "in preprocessor: "..err + end -- execute preprocessor local success, output = pcall(preprocess) - if not success then error("Error while preprocessing file: " .. output) end + if not success then + return nil, "in preprocessor: "..output + end return output end @@ -144,14 +155,16 @@ end --- Run the compiler -- @tparam input string input code -- @tparam options table options for the compiler --- @treturn output string output code +-- @treturn[1] output string output code +-- @treturn[2] nil nil if error +-- @treturn[2] error string error message function candran.compile(input, options={}) options = util.merge(candran.default, options) local ast, errmsg = parser.parse(input, options.chunkname) if not ast then - error("Compiler: error while parsing file: "..errmsg) + return nil, errmsg end return require("compiler."..options.target)(input, ast, options) @@ -160,9 +173,18 @@ end --- Preprocess & compile code -- @tparam code string input code -- @tparam options table arguments for the preprocessor and compiler --- @treturn output string output code +-- @treturn[1] output string output code +-- @treturn[2] nil nil if error +-- @treturn[2] error string error message function candran.make(code, options) - return candran.compile(candran.preprocess(code, options), options) + local r, err = candran.preprocess(code, options) + if r then + r, err = candran.compile(r, options) + if r then + return r + end + end + return r, err end local errorRewritingActive = false @@ -171,7 +193,9 @@ local codeCache = {} -- Will rewrite errors by default. function candran.loadfile(filepath, env, options) local f, err = io.open(filepath) - if not f then error("can't open the file: "..err) end + if not f then + return nil, "cannot open %s":format(err) + end local content = f:read("*a") f:close() @@ -183,14 +207,19 @@ end function candran.load(chunk, chunkname, env, options={}) options = util.merge({ chunkname = tostring(chunkname or chunk) }, options) - codeCache[options.chunkname] = candran.make(chunk, options) - local f, err = util.load(codeCache[options.chunkname], options.chunkname, env) + local code, err = candran.make(chunk, options) + if not code then + return code, err + end + + codeCache[options.chunkname] = code + local f, err = util.load(code, options.chunkname, env) -- Um. Candran isn't supposed to generate invalid Lua code, so this is a major issue. -- This is not going to raise an error because this is supposed to behave similarly to Lua's load function. -- But the error message will likely be useless unless you know how Candran works. if f == nil then - return f, "Candran unexpectedly generated invalid code: "..err + return f, "candran unexpectedly generated invalid code: "..err end if options.rewriteErrors == false then @@ -248,7 +277,7 @@ function candran.messageHandler(message) if originalFile then local i = 0 - for l in originalFile:gmatch("([^\n]*)\n") do + for l in (originalFile.."\n"):gmatch("([^\n]*)\n") do i = i +1 if i == line then local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") diff --git a/candran.lua b/candran.lua index bc6f34a..8ea939c 100644 --- a/candran.lua +++ b/candran.lua @@ -299,7 +299,7 @@ local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 @@ -1155,7 +1155,7 @@ local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 @@ -1838,7 +1838,7 @@ 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 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/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 @@ -2049,7 +2049,7 @@ local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 end -- ./compiler/lua53.can:183 local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 end -- ./compiler/lua53.can:186 local CONTINUE_START = function() -- ./compiler/lua53.can:188 return "do" .. indent() -- ./compiler/lua53.can:189 @@ -2732,7 +2732,7 @@ 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 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/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 @@ -4485,7 +4485,7 @@ return parser -- ./candran/can-parser/parser.lua:744 end -- ./candran/can-parser/parser.lua:744 local parser = _() or parser -- ./candran/can-parser/parser.lua:748 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:749 -local candran = { ["VERSION"] = "0.11.0" } -- candran.can:14 +local candran = { ["VERSION"] = "0.12.0" } -- candran.can:14 candran["default"] = { -- candran.can:18 ["target"] = "lua53", -- candran.can:19 ["indentation"] = "", -- candran.can:20 @@ -4503,212 +4503,228 @@ else -- candran.can:31 candran["default"]["target"] = "lua51" -- candran.can:33 end -- candran.can:33 end -- candran.can:33 -candran["preprocess"] = function(input, options) -- candran.can:41 -if options == nil then options = {} end -- candran.can:41 -options = util["merge"](candran["default"], options) -- candran.can:42 -local preprocessor = "" -- candran.can:45 -local i = 0 -- candran.can:46 -local inLongString = false -- candran.can:47 -local inComment = false -- candran.can:48 +candran["preprocess"] = function(input, options) -- candran.can:43 +if options == nil then options = {} end -- candran.can:43 +options = util["merge"](candran["default"], options) -- candran.can:44 +local preprocessor = "" -- candran.can:47 +local i = 0 -- candran.can:48 +local inLongString = false -- candran.can:49 +local inComment = false -- candran.can:50 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:49 -i = i + (1) -- candran.can:50 -if inComment then -- candran.can:52 -inComment = not line:match("%]%]") -- candran.can:53 -elseif inLongString then -- candran.can:54 -inLongString = not line:match("%]%]") -- candran.can:55 -else -- candran.can:55 -if line:match("[^%-]%[%[") then -- candran.can:57 -inLongString = true -- candran.can:58 -elseif line:match("%-%-%[%[") then -- candran.can:59 -inComment = true -- candran.can:60 -end -- candran.can:60 -end -- candran.can:60 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:63 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:64 -else -- candran.can:64 -local l = line:sub(1, - 2) -- candran.can:66 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:67 +)") do -- candran.can:51 +i = i + (1) -- candran.can:52 +if inComment then -- candran.can:54 +inComment = not line:match("%]%]") -- candran.can:55 +elseif inLongString then -- candran.can:56 +inLongString = not line:match("%]%]") -- candran.can:57 +else -- candran.can:57 +if line:match("[^%-]%[%[") then -- candran.can:59 +inLongString = true -- candran.can:60 +elseif line:match("%-%-%[%[") then -- candran.can:61 +inComment = true -- candran.can:62 +end -- candran.can:62 +end -- candran.can:62 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:65 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:66 +else -- candran.can:66 +local l = line:sub(1, - 2) -- candran.can:68 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:69 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:68 -else -- candran.can:68 -preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ ") -- candran.can:70 -end -- candran.can:70 -end -- candran.can:70 -end -- candran.can:70 -preprocessor = preprocessor .. ("return output") -- candran.can:74 -local env = util["merge"](_G, options) -- candran.can:77 -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, { -- 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 -end -- candran.can:93 -margs = util["merge"](options, { -- candran.can:95 -["chunkname"] = filepath, -- candran.can:95 -["loadLocal"] = true, -- candran.can:95 -["loadPackage"] = true -- candran.can:95 -}, margs) -- candran.can:95 -local modcontent = candran["preprocess"](f:read("*a"), margs) -- candran.can:96 -f:close() -- candran.can:97 -local modname = modpath:match("[^%.]+$") -- candran.can:100 +else -- candran.can:70 +preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ +") -- candran.can:72 +end -- candran.can:72 +end -- candran.can:72 +end -- candran.can:72 +preprocessor = preprocessor .. ("return output") -- candran.can:76 +local env = util["merge"](_G, options) -- candran.can:79 +env["candran"] = candran -- candran.can:81 +env["output"] = "" -- candran.can:83 +env["import"] = function(modpath, margs) -- candran.can:90 +if margs == nil then margs = {} end -- candran.can:90 +local filepath = assert(util["search"](modpath, { -- candran.can:91 +"can", -- candran.can:91 +"lua" -- candran.can:91 +}), "No module named \"" .. modpath .. "\"") -- candran.can:91 +local f = io["open"](filepath) -- candran.can:94 +if not f then -- candran.can:95 +error("can't open the module file to import") -- candran.can:95 +end -- candran.can:95 +margs = util["merge"](options, { -- candran.can:97 +["chunkname"] = filepath, -- candran.can:97 +["loadLocal"] = true, -- candran.can:97 +["loadPackage"] = true -- candran.can:97 +}, margs) -- candran.can:97 +local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:98 +f:close() -- candran.can:99 +local modname = modpath:match("[^%.]+$") -- candran.can:102 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:109 -end -- candran.can:109 -env["include"] = function(file) -- candran.can:114 -local f = io["open"](file) -- candran.can:115 -if not f then -- candran.can:116 -error("Can't open the file " .. file .. " to include") -- candran.can:116 -end -- candran.can:116 -env["write"](f:read("*a")) -- candran.can:117 -f:close() -- candran.can:118 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:111 +end -- candran.can:111 +env["include"] = function(file) -- candran.can:116 +local f = io["open"](file) -- candran.can:117 +if not f then -- candran.can:118 +error("can't open the file " .. file .. " to include") -- candran.can:118 end -- candran.can:118 -env["write"] = function(...) -- candran.can:122 +env["write"](f:read("*a")) -- candran.can:119 +f:close() -- candran.can:120 +end -- candran.can:120 +env["write"] = function(...) -- candran.can:124 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:123 -end -- candran.can:123 -env["placeholder"] = function(name) -- candran.can:127 -if env[name] then -- candran.can:128 -env["write"](env[name]) -- candran.can:129 -end -- candran.can:129 -end -- candran.can:129 -local preprocess, err = util["load"](candran["compile"](preprocessor, args), "candran preprocessor", env) -- candran.can:134 -if not preprocess then -- candran.can:135 -error("Error while creating Candran preprocessor: " .. err) -- candran.can:135 -end -- candran.can:135 -local success, output = pcall(preprocess) -- candran.can:138 -if not success then -- candran.can:139 -error("Error while preprocessing file: " .. output) -- candran.can:139 -end -- candran.can:139 -return output -- candran.can:141 -end -- candran.can:141 -candran["compile"] = function(input, options) -- candran.can:148 -if options == nil then options = {} end -- candran.can:148 -options = util["merge"](candran["default"], options) -- candran.can:149 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:151 -if not ast then -- candran.can:153 -error("Compiler: error while parsing file: " .. errmsg) -- candran.can:154 -end -- candran.can:154 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:157 -end -- candran.can:157 -candran["make"] = function(code, options) -- candran.can:164 -return candran["compile"](candran["preprocess"](code, options), options) -- candran.can:165 -end -- candran.can:165 -local errorRewritingActive = false -- candran.can:168 -local codeCache = {} -- candran.can:169 -candran["loadfile"] = function(filepath, env, options) -- candran.can:172 -local f, err = io["open"](filepath) -- candran.can:173 -if not f then -- candran.can:174 -error("can't open the file: " .. err) -- candran.can:174 -end -- candran.can:174 -local content = f:read("*a") -- candran.can:175 -f:close() -- candran.can:176 -return candran["load"](content, filepath, env, options) -- candran.can:178 -end -- candran.can:178 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:183 -if options == nil then options = {} end -- candran.can:183 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:184 -codeCache[options["chunkname"]] = candran["make"](chunk, options) -- candran.can:186 -local f, err = util["load"](codeCache[options["chunkname"]], options["chunkname"], env) -- candran.can:187 -if f == nil then -- candran.can:192 -return f, "Candran unexpectedly generated invalid code: " .. err -- candran.can:193 -end -- candran.can:193 -if options["rewriteErrors"] == false then -- candran.can:196 -return f -- candran.can:197 -else -- candran.can:197 -return function(...) -- candran.can:199 -local params = { ... } -- candran.can:200 -if not errorRewritingActive then -- candran.can:201 -errorRewritingActive = true -- candran.can:202 -local t = { xpcall(function() -- candran.can:203 -return f(unpack(params)) -- candran.can:203 -end, candran["messageHandler"]) } -- candran.can:203 -errorRewritingActive = false -- candran.can:204 -if t[1] == false then -- candran.can:205 -error(t[2], 0) -- candran.can:206 -end -- candran.can:206 -return unpack(t, 2) -- candran.can:208 -else -- candran.can:208 -return f(...) -- candran.can:210 -end -- candran.can:210 -end -- candran.can:210 -end -- candran.can:210 -end -- candran.can:210 -candran["dofile"] = function(filename, options) -- candran.can:218 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:219 +") -- candran.can:125 +end -- candran.can:125 +env["placeholder"] = function(name) -- candran.can:129 +if env[name] then -- candran.can:130 +env["write"](env[name]) -- candran.can:131 +end -- candran.can:131 +end -- candran.can:131 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:136 +if not preprocess then -- candran.can:137 +return nil, "in preprocessor: " .. err -- candran.can:138 +end -- candran.can:138 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:141 +if not preprocess then -- candran.can:142 +return nil, "in preprocessor: " .. err -- candran.can:143 +end -- candran.can:143 +local success, output = pcall(preprocess) -- candran.can:147 +if not success then -- candran.can:148 +return nil, "in preprocessor: " .. output -- candran.can:149 +end -- candran.can:149 +return output -- candran.can:152 +end -- candran.can:152 +candran["compile"] = function(input, options) -- candran.can:161 +if options == nil then options = {} end -- candran.can:161 +options = util["merge"](candran["default"], options) -- candran.can:162 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:164 +if not ast then -- candran.can:166 +return nil, errmsg -- candran.can:167 +end -- candran.can:167 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:170 +end -- candran.can:170 +candran["make"] = function(code, options) -- candran.can:179 +local r, err = candran["preprocess"](code, options) -- candran.can:180 +if r then -- candran.can:181 +r, err = candran["compile"](r, options) -- candran.can:182 +if r then -- candran.can:183 +return r -- candran.can:184 +end -- candran.can:184 +end -- candran.can:184 +return r, err -- candran.can:187 +end -- candran.can:187 +local errorRewritingActive = false -- candran.can:190 +local codeCache = {} -- candran.can:191 +candran["loadfile"] = function(filepath, env, options) -- candran.can:194 +local f, err = io["open"](filepath) -- candran.can:195 +if not f then -- candran.can:196 +return nil, ("cannot open %s"):format(err) -- candran.can:197 +end -- candran.can:197 +local content = f:read("*a") -- candran.can:199 +f:close() -- candran.can:200 +return candran["load"](content, filepath, env, options) -- candran.can:202 +end -- candran.can:202 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:207 +if options == nil then options = {} end -- candran.can:207 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:208 +local code, err = candran["make"](chunk, options) -- candran.can:210 +if not code then -- candran.can:211 +return code, err -- candran.can:212 +end -- candran.can:212 +codeCache[options["chunkname"]] = code -- candran.can:215 +local f, err = util["load"](code, options["chunkname"], env) -- candran.can:216 if f == nil then -- candran.can:221 -error(err) -- candran.can:222 -else -- candran.can:222 -return f() -- candran.can:224 -end -- candran.can:224 -end -- candran.can:224 -candran["messageHandler"] = function(message) -- candran.can:230 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:222 +end -- candran.can:222 +if options["rewriteErrors"] == false then -- candran.can:225 +return f -- candran.can:226 +else -- candran.can:226 +return function(...) -- candran.can:228 +local params = { ... } -- candran.can:229 +if not errorRewritingActive then -- candran.can:230 +errorRewritingActive = true -- candran.can:231 +local t = { xpcall(function() -- candran.can:232 +return f(unpack(params)) -- candran.can:232 +end, candran["messageHandler"]) } -- candran.can:232 +errorRewritingActive = false -- candran.can:233 +if t[1] == false then -- candran.can:234 +error(t[2], 0) -- candran.can:235 +end -- candran.can:235 +return unpack(t, 2) -- candran.can:237 +else -- candran.can:237 +return f(...) -- candran.can:239 +end -- candran.can:239 +end -- candran.can:239 +end -- candran.can:239 +end -- candran.can:239 +candran["dofile"] = function(filename, options) -- candran.can:247 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:248 +if f == nil then -- candran.can:250 +error(err) -- candran.can:251 +else -- candran.can:251 +return f() -- candran.can:253 +end -- candran.can:253 +end -- candran.can:253 +candran["messageHandler"] = function(message) -- candran.can:259 return debug["traceback"](message, 2):gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:231 -line = tonumber(line) -- candran.can:232 -local originalFile -- candran.can:234 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:235 -if strName then -- candran.can:236 -if codeCache[strName] then -- candran.can:237 -originalFile = codeCache[strName] -- candran.can:238 -source = strName -- candran.can:239 -end -- candran.can:239 -else -- candran.can:239 -local fi = io["open"](source, "r") -- candran.can:242 -if fi then -- candran.can:243 -originalFile = fi:read("*a") -- candran.can:244 -fi:close() -- candran.can:245 -end -- candran.can:245 -end -- candran.can:245 -if originalFile then -- candran.can:249 -local i = 0 -- candran.can:250 -for l in originalFile:gmatch("([^\ +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:260 +line = tonumber(line) -- candran.can:261 +local originalFile -- candran.can:263 +local strName = source:match("%[string \"(.-)\"%]") -- candran.can:264 +if strName then -- candran.can:265 +if codeCache[strName] then -- candran.can:266 +originalFile = codeCache[strName] -- candran.can:267 +source = strName -- candran.can:268 +end -- candran.can:268 +else -- candran.can:268 +local fi = io["open"](source, "r") -- candran.can:271 +if fi then -- candran.can:272 +originalFile = fi:read("*a") -- candran.can:273 +fi:close() -- candran.can:274 +end -- candran.can:274 +end -- candran.can:274 +if originalFile then -- candran.can:278 +local i = 0 -- candran.can:279 +for l in (originalFile .. "\ +"):gmatch("([^\ ]*)\ -") do -- candran.can:251 -i = i + 1 -- candran.can:252 -if i == line then -- candran.can:253 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:254 -if lineMap then -- candran.can:255 -if extSource ~= source then -- candran.can:256 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:257 -else -- candran.can:257 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:259 -end -- candran.can:259 -end -- candran.can:259 -break -- candran.can:262 -end -- candran.can:262 -end -- candran.can:262 -end -- candran.can:262 -end) -- candran.can:262 -end -- candran.can:262 -candran["searcher"] = function(modpath) -- candran.can:270 -local filepath = util["search"](modpath, { "can" }) -- candran.can:271 -if not filepath then -- candran.can:272 +") do -- candran.can:280 +i = i + 1 -- candran.can:281 +if i == line then -- candran.can:282 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:283 +if lineMap then -- candran.can:284 +if extSource ~= source then -- candran.can:285 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:286 +else -- candran.can:286 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:288 +end -- candran.can:288 +end -- candran.can:288 +break -- candran.can:291 +end -- candran.can:291 +end -- candran.can:291 +end -- candran.can:291 +end) -- candran.can:291 +end -- candran.can:291 +candran["searcher"] = function(modpath) -- candran.can:299 +local filepath = util["search"](modpath, { "can" }) -- candran.can:300 +if not filepath then -- candran.can:301 return "\ -\9no candran file in package.path" -- candran.can:273 -end -- candran.can:273 -return candran["loadfile"](filepath) -- candran.can:275 -end -- candran.can:275 -candran["setup"] = function() -- candran.can:279 -if _VERSION == "Lua 5.1" then -- candran.can:280 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:281 -else -- candran.can:281 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:283 -end -- candran.can:283 -return candran -- candran.can:285 -end -- candran.can:285 -return candran -- candran.can:288 +\9no candran file in package.path" -- candran.can:302 +end -- candran.can:302 +return candran["loadfile"](filepath) -- candran.can:304 +end -- candran.can:304 +candran["setup"] = function() -- candran.can:308 +if _VERSION == "Lua 5.1" then -- candran.can:309 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:310 +else -- candran.can:310 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:312 +end -- candran.can:312 +return candran -- candran.can:314 +end -- candran.can:314 +return candran -- candran.can:317 diff --git a/compiler/lua53.can b/compiler/lua53.can index 7e390df..5dabc03 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -183,7 +183,7 @@ return function(code, ast, options) 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 "..var("a").." = table.pack("..toAppend..")"..newline().."table.move("..var("a")..", 1, "..var("a")..".n, #"..t.."+1, "..t..")"..unindent().."end" end local CONTINUE_START = () -- at the start of loops using continue return "do"..indent() diff --git a/compiler/luajit.can b/compiler/luajit.can index a4d068b..9428fc5 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -4,7 +4,7 @@ UNPACK = (list, i, j) return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" end APPEND = (t, toAppend) - 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" + return "do" .. indent() .. "local "..var("a")..", "..var("p").." = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #"..var("a").." do" .. indent() .. t .. "["..var("p").."] = "..var("a").."[i]" .. newline() .. ""..var("p").." = "..var("p").." + 1" .. unindent() .. "end" .. unindent() .. "end" end tags._opid.idiv = (left, right) diff --git a/rockspec/candran-scm-1.rockspec b/rockspec/candran-scm-1.rockspec index f12891e..c6573dd 100644 --- a/rockspec/candran-scm-1.rockspec +++ b/rockspec/candran-scm-1.rockspec @@ -23,7 +23,9 @@ source = { dependencies = { "lua >= 5.1", - "lpeglabel >= 1.5.0" + "lpeglabel >= 1.5.0", + "linenoise >= 0.9", + "luacheck >= 0.23.0" } build = { @@ -32,6 +34,6 @@ build = { candran = "candran.lua" }, install = { - bin = { "bin/can", "bin/canc" } + bin = { "bin/can", "bin/canc", "bin/cancheck" } } } diff --git a/test/test.lua b/test/test.lua index 1588ab0..62ef409 100644 --- a/test/test.lua +++ b/test/test.lua @@ -15,7 +15,7 @@ local function test(name, candranCode, expectedResult, options) options.chunkname = name -- make code - local success, code = pcall(candran.make, candranCode, options) + local success, code = pcall(function() return assert(candran.make(candranCode, options)) end) if not success then self.result = "error" self.message = "/!\\ error while making code:\n"..code From 33ac4c5d7f8bdd6edbb01cfa409846d618ba4cf9 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 6 Apr 2020 23:11:17 +0200 Subject: [PATCH 11/52] Discard warnings from external files in cancheck --- bin/can | 2 +- bin/canc | 8 ++-- bin/cancheck | 130 +++++++++++++++++++++++++++++++++++---------------- 3 files changed, 96 insertions(+), 44 deletions(-) diff --git a/bin/can b/bin/can index 9076123..a960e00 100644 --- a/bin/can +++ b/bin/can @@ -32,7 +32,7 @@ if arg[#arg] == "-" then elseif #args >= 1 then local f, err = candran.loadfile(args[1], nil, args) if not f then - print("can: "..err) + io.stderr:write("can: "..err.."\n") os.exit(1) else f() diff --git a/bin/canc b/bin/canc index c73d368..b87cb8f 100644 --- a/bin/canc +++ b/bin/canc @@ -46,7 +46,7 @@ for _, file in ipairs(args) do local inputFile, err = io.open(file, "r") if not inputFile then - io.stderr:write("canc: cannot open "..file..": "..err) + io.stderr:write("canc: cannot open "..file..": "..err.."\n") os.exit(1) end input = inputFile:read("*a") @@ -81,7 +81,7 @@ for _, file in ipairs(args) do if args.preprocess then local r, err = candran.preprocess(out, args) if not r then - print("canc: "..err) + io.stderr:write("canc: "..err.."\n") os.exit(1) end out = r @@ -89,7 +89,7 @@ for _, file in ipairs(args) do if args.compile then local r, err = candran.compile(out, args) if not r then - print("canc: "..err) + io.stderr:write("canc: "..err.."\n") os.exit(1) end out = r @@ -97,7 +97,7 @@ for _, file in ipairs(args) do if args.compile == nil and args.preprocess == nil then local r, err = candran.make(input, args) if not r then - print("canc: "..err) + io.stderr:write("canc: "..err.."\n") os.exit(1) end out = r diff --git a/bin/cancheck b/bin/cancheck index df59191..5354d40 100644 --- a/bin/cancheck +++ b/bin/cancheck @@ -2,9 +2,14 @@ -- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files local candran = require("candran") +local util = require("candran.util") + +local function escape(str) + return str:gsub("[^%w]", "%%%0") +end local function pattern(token) - return "()"..token:gsub("[^%w]", "%%%0").."()" + return "()"..escape(token).."()" end local tokenAlias = { @@ -14,7 +19,8 @@ local tokenAlias = { -- Patch checker local oldCheck = require("luacheck.check") local function check(can) - local lua, err = candran.make(can) + local lua, err = candran.make(can, {chunkname="_luacheck_source"}) + -- Warnings if lua then local r = oldCheck(lua) -- Calculate Candran file position. @@ -27,50 +33,72 @@ local function check(can) for l in (can.."\n"):gmatch("([^\n]*)\n") do table.insert(can_lines, l) end - for _, warning in ipairs(r.warnings) do - -- candran line - local lua_line = lua_lines[warning.line] - warning.can_line = tonumber(lua_line:match(".*%-%- .-%:(%d+)$")) + for i=#r.warnings, 1, -1 do + local warning = r.warnings[i] - -- candran column - local can_line = can_lines[warning.can_line] - local lua_token = lua_line:sub(warning.column, warning.end_column) - local token_pattern = pattern(lua_token) -- token finding pattern - -- the warning happens on the n-th instance of lua_token on this line - local lua_n = 1 - for start in lua_line:gmatch(token_pattern) do - if start >= warning.column then - break - end - lua_n = lua_n + 1 - end - -- Find associated candran token. If lua_n > can_nmax, the last found lua_token is used. - -- This approximation should work in like, 90% of cases. - local can_n = 1 - local pos = 1 - while can_n <= lua_n do - -- find first token or alias of this token - local start, stop = can_line:match(token_pattern, pos) - if tokenAlias[lua_token] then - for _, token in ipairs(tokenAlias[lua_token]) do - local nstart, nstop = can_line:match(pattern(token), pos) - if nstart and (not start or nstart < start) then - start, stop = nstart, nstop - end + -- calculating candran line + local lua_line = lua_lines[warning.line] + + local source, line = lua_line:match(".*%-%- (.-)%:(%d+)$") + if source ~= "_luacheck_source" then -- line is from another file, discard + table.remove(r.warnings, i) + + elseif source then + warning.can_line = tonumber(line) + + -- do the same for prev_line + if warning.prev_line then + local s, l = lua_lines[warning.prev_line]:match(".*%-%- (.-)%:(%d+)$") + if s ~= "_luacheck_source" then + warning.prev_line = s..":"..l -- luacheck seems to do no validation on this, so we can redefine it to anything + elseif l then + warning.prev_line = l end end - -- found - if start then - pos = stop - warning.can_column, warning.can_end_column = start, stop - can_n = can_n + 1 - else - break + + -- calculating candran column + local can_line = can_lines[warning.can_line] + local lua_token = lua_line:sub(warning.column, warning.end_column) + local token_pattern = pattern(lua_token) -- token finding pattern + -- the warning happens on the n-th instance of lua_token on this line + local lua_n = 1 + for start in lua_line:gmatch(token_pattern) do + if start >= warning.column then + break + end + lua_n = lua_n + 1 end + -- Find associated candran token. If lua_n > can_nmax, the last found lua_token is used. + -- This approximation should work in like, 90% of cases. + local can_n = 1 + local pos = 1 + while can_n <= lua_n do + -- find first token or alias of this token + local start, stop = can_line:match(token_pattern, pos) + if tokenAlias[lua_token] then + for _, token in ipairs(tokenAlias[lua_token]) do + local nstart, nstop = can_line:match(pattern(token), pos) + if nstart and (not start or nstart < start) then + start, stop = nstart, nstop + end + end + end + -- found + if start then + pos = stop + warning.can_column, warning.can_end_column = start, stop + can_n = can_n + 1 + else + break + end + end + + -- AFAIK, prev_column and prev_column_end are not displayed in any warning so we don't need to recalculate them for Candran. end end end return r + -- Syntax error else local line, column, msg = err:match(":(%d+):(%d+):%s*(.*)$") local syntax_error = { @@ -90,6 +118,14 @@ local function check(can) end package.loaded["luacheck.check"] = check +local runner = require("luacheck.runner") +local oldRunner = runner.new +function runner.new(opts) + -- Disable max line length checking (it is compiled code...) + opts.max_line_length = false + return oldRunner(opts) +end + -- Patch formatter local format = require("luacheck.format") local function format_location(file, location, opts) @@ -113,4 +149,20 @@ local function setupvalue(fn, val, name, ...) end setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location") -require("luacheck.main") +-- Fix some Luacheck messages and run +local path = util.search("luacheck.main", {"lua"}) +if path then + local f = io.open(path, "r") + local code = f:read("*a") + f:close() + + code = code:gsub(escape(" bug (please report at https://github.com/mpeterv/luacheck/issues)"), ", patched for Candran "..candran.VERSION.." bug. Please DO NOT report this bug to Luacheck") -- error text + :gsub(escape("\"luacheck\","), "\"cancheck\",") -- command name + :gsub("a linter and a static analyzer for Lua%.", "a linter and a static analyzer for Lua, patched for Candran "..candran.VERSION..".") -- help text + + -- run + return load(code)() +else + io.stderr:write("can't find luacheck.main\n") + os.exit(1) +end From 6edc682b21011ab59b4e60b411e06889689ce548 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 6 Apr 2020 23:30:48 +0200 Subject: [PATCH 12/52] Candran 0.12.0 --- README.md | 20 +++++-- bin/cancheck | 55 +++++++++++++++---- ...0-1.rockspec => candran-0.12.0-1.rockspec} | 9 +-- 3 files changed, 62 insertions(+), 22 deletions(-) rename rockspec/{candran-0.11.0-1.rockspec => candran-0.12.0-1.rockspec} (87%) diff --git a/README.md b/README.md index a715320..b5c2283 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,11 @@ end Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup -Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.11.0-1.rockspec```. +Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.12.0-1.rockspec```. Or manually install LPegLabel (```luarocks install lpeglabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. -You can optionally install lua-linenoise (```luarocks install linenoise```, version 0.9 or above) for an improved REPL. The rockspec will install linenoise by default. +You can optionally install lua-linenoise (```luarocks install linenoise```, version 0.9 or above) for an improved REPL, and luacheck (```luarocks install luacheck```, version 0.23.0 or above) to be able to use ```cancheck```. Installing Candran using LuaRocks will install linenoise and luacheck by default. You can register the Candran package searcher in your main Lua file (`require("candran").setup()`) and any subsequent `require` call in your project will automatically search for Candran modules. @@ -87,6 +87,8 @@ Most editors should be able to use their existing Lua support for Candran code. * [SublimeLinter-candran-contrib](https://github.com/Reuh/SublimeLinter-contrib-candran) SublimeLinter plugin for Candran * **Atom**: [language-candran](https://atom.io/packages/language-candran) support the full Candran syntax +For linting, if your editor support [luacheck](https://github.com/luarocks/luacheck), you should be able to replace it with ```cancheck``` (in this repository ```bin/cancheck```, or installed automatically if Candran was installed using LuaRocks), which is a wrapper around luacheck that monkey-patch it to support Candran. + The language ------------ ### Syntax additions @@ -495,7 +497,7 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Start a simplisitic Candran REPL. - If you want a better REPL (autocompletion, history, ability to move the cursor), install lua-linenoise: ```luarocks install linenoise```. + If you want a better REPL (autocompletion, history, ability to move the cursor), install lua-linenoise: ```luarocks install linenoise``` (automatically installed if Candran was installed using LuaRocks). * ````can [options] filename```` @@ -509,6 +511,12 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Use the ```-h``` or ```-help``` option to display a short help text. +* ```cancheck``` + + Provides a linter and static analyzer with the exact same interface as [luacheck](https://github.com/luarocks/luacheck). + + This requires luacheck: ```luarocks install luacheck``` (automatically installed if Candran was installed through LuaRocks). + ### Library usage Candran can also be used as a Lua library: ````lua @@ -534,9 +542,9 @@ The table returned by _require("candran")_ gives you access to: ##### Compiler & preprocessor * ````candran.VERSION````: Candran's version string (e.g. `"0.10.0"`). -* ````candran.preprocess(code[, options])````: return the Candran code _code_, preprocessed with the _options_ options table. -* ````candran.compile(code[, options])````: return the Candran code compiled to Lua with the _options_ option table. -* ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table. +* ````candran.preprocess(code[, options])````: return the Candran code _code_, preprocessed with the _options_ options table; or nil, err in case of error. +* ````candran.compile(code[, options])````: return the Candran code compiled to Lua with the _options_ option table; or nil, err in case of error. +* ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table; or nil, err in case of error. ##### Code loading helpers * ```candran.loadfile(filepath, env, options)```: Candran equivalent to the Lua 5.3's loadfile funtion. Will rewrite errors by default. diff --git a/bin/cancheck b/bin/cancheck index 5354d40..27315a1 100644 --- a/bin/cancheck +++ b/bin/cancheck @@ -1,17 +1,60 @@ #!/usr/bin/env lua +--[[ +Based on luacheck: https://github.com/luarocks/luacheck + +The MIT License (MIT) + +Copyright (c) 2014 - 2018 Peter Melnichenko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + -- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files local candran = require("candran") local util = require("candran.util") +-- set a function upvalues (if several names are given, will go up the upvalue chain) +local function setupvalue(fn, val, name, ...) + for i=1, debug.getinfo(fn, "u").nups do + local n, v = debug.getupvalue(fn, i) + if n == name then + if not ... then + debug.setupvalue(fn, i, val) + else + setupvalue(v, val, ...) + end + end + end +end + +-- escape a string to be used as a pattern local function escape(str) return str:gsub("[^%w]", "%%%0") end +-- returns a pattern that find start and stop position of a token local function pattern(token) return "()"..escape(token).."()" end +-- token aliases local tokenAlias = { ["self"] = { "@", ":" } } @@ -135,18 +178,6 @@ local function format_location(file, location, opts) end return res end -local function setupvalue(fn, val, name, ...) - for i=1, debug.getinfo(fn, "u").nups do - local n, v = debug.getupvalue(fn, i) - if n == name then - if not ... then - debug.setupvalue(fn, i, val) - else - setupvalue(v, val, ...) - end - end - end -end setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location") -- Fix some Luacheck messages and run diff --git a/rockspec/candran-0.11.0-1.rockspec b/rockspec/candran-0.12.0-1.rockspec similarity index 87% rename from rockspec/candran-0.11.0-1.rockspec rename to rockspec/candran-0.12.0-1.rockspec index fb04283..6e2588d 100644 --- a/rockspec/candran-0.11.0-1.rockspec +++ b/rockspec/candran-0.12.0-1.rockspec @@ -2,7 +2,7 @@ rockspec_format = "3.0" package = "candran" -version = "0.11.0-1" +version = "0.12.0-1" description = { summary = "A simple Lua dialect and preprocessor.", @@ -19,13 +19,14 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.11.0" + tag = "v0.12.0" } dependencies = { "lua >= 5.1", "lpeglabel >= 1.5.0", - "linenoise >= 0.9" + "linenoise >= 0.9", + "luacheck >= 0.23.0" } build = { @@ -34,6 +35,6 @@ build = { candran = "candran.lua" }, install = { - bin = { "bin/can", "bin/canc" } + bin = { "bin/can", "bin/canc", "bin/cancheck" } } } From 03516abb4517e6aaa4450356ec5bebfc74305503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Fildadut?= Date: Tue, 7 Apr 2020 00:05:50 +0200 Subject: [PATCH 13/52] Add SublimeLinter-contrib-cancheck to README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b5c2283..fa4d77f 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,8 @@ You can register the Candran package searcher in your main Lua file (`require("c Most editors should be able to use their existing Lua support for Candran code. If you want full support for the additional syntax in your editor: * **Sublime Text 3**: * [sublime-candran](https://github.com/Reuh/sublime-candran) support the full Candran syntax - * [SublimeLinter-candran-contrib](https://github.com/Reuh/SublimeLinter-contrib-candran) SublimeLinter plugin for Candran + * [SublimeLinter-cancheck-contrib](https://github.com/Reuh/SublimeLinter-contrib-cancheck) SublimeLinter plugin for Candran using ```cancheck``` + * [SublimeLinter-candran-contrib](https://github.com/Reuh/SublimeLinter-contrib-candran) SublimeLinter plugin for Candran using ```canc -parse``` (only checks for syntaxic errors, no linting) * **Atom**: [language-candran](https://atom.io/packages/language-candran) support the full Candran syntax For linting, if your editor support [luacheck](https://github.com/luarocks/luacheck), you should be able to replace it with ```cancheck``` (in this repository ```bin/cancheck```, or installed automatically if Candran was installed using LuaRocks), which is a wrapper around luacheck that monkey-patch it to support Candran. From 7add585c03c0ce2a9b6c4cb8b8cdbe19b4305c5f Mon Sep 17 00:00:00 2001 From: Reuh Date: Tue, 7 Apr 2020 00:16:39 +0200 Subject: [PATCH 14/52] Fix end_column being off by one in cancheck --- bin/cancheck | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/cancheck b/bin/cancheck index 27315a1..61cc964 100644 --- a/bin/cancheck +++ b/bin/cancheck @@ -129,14 +129,14 @@ local function check(can) -- found if start then pos = stop - warning.can_column, warning.can_end_column = start, stop + warning.can_column, warning.can_end_column = start, stop-1 can_n = can_n + 1 else break end end - -- AFAIK, prev_column and prev_column_end are not displayed in any warning so we don't need to recalculate them for Candran. + -- AFAIK, prev_column and prev_end_column are not displayed in any warning so we don't need to recalculate them for Candran. end end end From 10be62a2fe6ada7ba640cb58faf3345c0d915705 Mon Sep 17 00:00:00 2001 From: Reuh Date: Tue, 30 Jun 2020 21:29:13 +0200 Subject: [PATCH 15/52] Lua 5.4 support and const and close shortcut --- README.md | 37 +- candran.can | 9 +- candran.lua | 7720 ++++++++++++++++++--------------- candran/can-parser/parser.lua | 45 +- compiler/lua53.can | 831 +--- compiler/lua54.can | 835 ++++ 6 files changed, 5205 insertions(+), 4272 deletions(-) create mode 100644 compiler/lua54.can diff --git a/README.md b/README.md index fa4d77f..b74a2eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Candran ======= -Candran is a dialect of the [Lua 5.3](http://www.lua.org) programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. +Candran is a dialect of the [Lua 5.4](http://www.lua.org) programming language which compiles to Lua 5.4, Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. @@ -31,6 +31,8 @@ let a = { end } +const five = 5 -- shortcut for Lua 5.4 attributes + a:method(42, (foo) return "something " .. foo end) @@ -172,8 +174,22 @@ let a = { Similar to ```local```, but the variable will be declared *before* the assignemnt (i.e. it will compile into ```local a; a = value```), so you can access it from functions defined in the value. +This does not support Lua 5.4 attributes. + Can also be used as a shorter name for ```local```. +##### `const` and `close` variable declaration +```lua +const a = 5 +close b = {} + +const x, y, z = 1, 2, 3 -- every variable will be defined using +``` + +Shortcut to Lua 5.4 variable attribute. Do not behave like `let`, as attributes require the variable to be constant and therefore can't be predeclared. + +_Not in the latest release._ + ##### `continue` keyword ```lua for i=1, 10 do @@ -435,13 +451,18 @@ The preprocessor has access to the following variables: Compile targets --------------- -Candran is based on the Lua 5.3 syntax, but can be compiled to Lua 5.3, LuaJIT, and Lua 5.1 compatible code. +Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, LuaJIT, and Lua 5.1 compatible code. -To chose a compile target, set the ```target``` option to ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. +To chose a compile target, set the ```target``` option to ```lua54```, ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. -For the ```luajit``` and ```lua51``` targets, Lua 5.3 specific syntax (bitwise operators, integer division) will automatically be translated to valid Lua 5.1 syntax, using LuaJIT's ```bit``` library if necessary. Unless LuaJIT's bit library is installed, you won't be able to use bitwise operators with vanilla Lua 5.1 ("PUC Lua"). +Candran will try to translate Lua 5.4 syntax into something usable with the current target if possible. Here is what is currently supported: -The ```lua51``` target does not support gotos and labels. +| Lua version | Candran target | Integer division operator // | Bitwise operators | Goto/Labels | Variable attributes | +| --- | --- | --- | --- | --- | --- | +| Lua 5.4 | lua54 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Lua 5.3 | lua53 | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | +| LuaJIT | luajit | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | +| Lua 5.2/5.1 | lua51 | :white_check_mark: | :white_check_mark: if LuaJIT bit library is available | X | X | **Please note** that Candran only translates syntax, and will not try to do anything about changes in the Lua standard library (for example, the new utf8 module). If you need this, you should be able to use [lua-compat-5.3](https://github.com/keplerproject/lua-compat-5.3) along with Candran. @@ -548,9 +569,9 @@ The table returned by _require("candran")_ gives you access to: * ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table; or nil, err in case of error. ##### Code loading helpers -* ```candran.loadfile(filepath, env, options)```: Candran equivalent to the Lua 5.3's loadfile funtion. Will rewrite errors by default. -* ```candran.load(chunk, chunkname, env, options)```: Candran equivalent to the Lua 5.3's load funtion. Will rewrite errors by default. -* ```candran.dofile(filepath, options)```: Candran equivalent to the Lua 5.3's dofile funtion. Will rewrite errors by default. +* ```candran.loadfile(filepath, env, options)```: Candran equivalent to the Lua 5.4's loadfile funtion. Will rewrite errors by default. +* ```candran.load(chunk, chunkname, env, options)```: Candran equivalent to the Lua 5.4's load funtion. Will rewrite errors by default. +* ```candran.dofile(filepath, options)```: Candran equivalent to the Lua 5.4's dofile funtion. Will rewrite errors by default. #### Error rewriting When using the command-line tools or the code loading helpers, Candran will automatically setup error rewriting: because the code is reformated when diff --git a/candran.can b/candran.can index 2022852..326ac0c 100644 --- a/candran.can +++ b/candran.can @@ -1,6 +1,7 @@ #import("candran.util") #import("candran.cmdline") +#import("compiler.lua54") #import("compiler.lua53") #import("compiler.luajit") #import("compiler.lua51") @@ -11,12 +12,12 @@ #import("candran.can-parser.parser") local candran = { - VERSION = "0.12.0" + VERSION = "0.13.0" } --- Default options. candran.default = { - target = "lua53", + target = "lua54", indentation = "", newline = "\n", variablePrefix = "__CAN_", @@ -32,6 +33,10 @@ if _VERSION == "Lua 5.1" then else candran.default.target = "lua51" end +elseif _VERSION == "Lua 5.2" then + candran.default.target = "lua51" +elseif _VERSION == "Lua 5.3" then + --candran.default.target = "lua53" end --- Run the preprocessor diff --git a/candran.lua b/candran.lua index 8ea939c..5ff75d4 100644 --- a/candran.lua +++ b/candran.lua @@ -129,1749 +129,2603 @@ end -- ./candran/cmdline.lua:125 local cmdline = _() or cmdline -- ./candran/cmdline.lua:130 package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua:131 local function _() -- ./candran/cmdline.lua:135 -local targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -return function(code, ast, options) -- ./compiler/lua53.can:3 -local lastInputPos = 1 -- ./compiler/lua53.can:5 -local prevLinePos = 1 -- ./compiler/lua53.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 -local lastLine = 1 -- ./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 targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +return function(code, ast, options) -- ./compiler/lua54.can:3 +local lastInputPos = 1 -- ./compiler/lua54.can:5 +local prevLinePos = 1 -- ./compiler/lua54.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 +local lastLine = 1 -- ./compiler/lua54.can:8 +local indentLevel = 0 -- ./compiler/lua54.can:11 +local function newline() -- ./compiler/lua54.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 +if options["mapLines"] then -- ./compiler/lua54.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./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 +") -- ./compiler/lua54.can:17 +if source and line then -- ./compiler/lua54.can:19 +lastSource = source -- ./compiler/lua54.can:20 +lastLine = tonumber(line) -- ./compiler/lua54.can:21 +else -- ./compiler/lua54.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") 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 -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 states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- ./compiler/lua53.can:49 -["scope"] = {} -- ./compiler/lua53.can:50 -} -- ./compiler/lua53.can:50 -local function push(name, state) -- ./compiler/lua53.can:53 -table["insert"](states[name], state) -- ./compiler/lua53.can:54 -return "" -- ./compiler/lua53.can:55 -end -- ./compiler/lua53.can:55 -local function pop(name) -- ./compiler/lua53.can:58 -table["remove"](states[name]) -- ./compiler/lua53.can:59 -return "" -- ./compiler/lua53.can:60 -end -- ./compiler/lua53.can:60 -local function set(name, state) -- ./compiler/lua53.can:63 -states[name][# states[name]] = state -- ./compiler/lua53.can:64 -return "" -- ./compiler/lua53.can:65 -end -- ./compiler/lua53.can:65 -local function peek(name) -- ./compiler/lua53.can:68 -return states[name][# states[name]] -- ./compiler/lua53.can:69 -end -- ./compiler/lua53.can:69 -local function var(name) -- ./compiler/lua53.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:75 -end -- ./compiler/lua53.can:75 -local function tmp() -- ./compiler/lua53.can:79 -local scope = peek("scope") -- ./compiler/lua53.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 -table["insert"](scope, var) -- ./compiler/lua53.can:82 -return var -- ./compiler/lua53.can:83 -end -- ./compiler/lua53.can:83 -local required = {} -- ./compiler/lua53.can:87 -local requireStr = "" -- ./compiler/lua53.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 -if not required[req] then -- ./compiler/lua53.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 -required[req] = true -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -local loop = { -- ./compiler/lua53.can:99 -"While", -- ./compiler/lua53.can:99 -"Repeat", -- ./compiler/lua53.can:99 -"Fornum", -- ./compiler/lua53.can:99 -"Forin", -- ./compiler/lua53.can:99 -"WhileExpr", -- ./compiler/lua53.can:99 -"RepeatExpr", -- ./compiler/lua53.can:99 -"FornumExpr", -- ./compiler/lua53.can:99 -"ForinExpr" -- ./compiler/lua53.can:99 -} -- ./compiler/lua53.can:99 -local func = { -- ./compiler/lua53.can:100 -"Function", -- ./compiler/lua53.can:100 -"TableCompr", -- ./compiler/lua53.can:100 -"DoExpr", -- ./compiler/lua53.can:100 -"WhileExpr", -- ./compiler/lua53.can:100 -"RepeatExpr", -- ./compiler/lua53.can:100 -"IfExpr", -- ./compiler/lua53.can:100 -"FornumExpr", -- ./compiler/lua53.can:100 -"ForinExpr" -- ./compiler/lua53.can:100 -} -- ./compiler/lua53.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 -local tagsCheck = {} -- ./compiler/lua53.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 -tagsCheck[tag] = true -- ./compiler/lua53.can:107 -end -- ./compiler/lua53.can:107 -local nofollowCheck = {} -- ./compiler/lua53.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 -nofollowCheck[tag] = true -- ./compiler/lua53.can:111 -end -- ./compiler/lua53.can:111 -for _, node in ipairs(list) do -- ./compiler/lua53.can:113 -if type(node) == "table" then -- ./compiler/lua53.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 -return node -- ./compiler/lua53.can:116 -end -- ./compiler/lua53.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 -if r then -- ./compiler/lua53.can:120 -return r -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -return nil -- ./compiler/lua53.can:124 -end -- ./compiler/lua53.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 -local tagsCheck = {} -- ./compiler/lua53.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 -tagsCheck[tag] = true -- ./compiler/lua53.can:132 -end -- ./compiler/lua53.can:132 -local nofollowCheck = {} -- ./compiler/lua53.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 -nofollowCheck[tag] = true -- ./compiler/lua53.can:136 -end -- ./compiler/lua53.can:136 -local found = {} -- ./compiler/lua53.can:138 -for _, node in ipairs(list) do -- ./compiler/lua53.can:139 -if type(node) == "table" then -- ./compiler/lua53.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 -table["insert"](found, n) -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 -table["insert"](found, node) -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -return found -- ./compiler/lua53.can:151 -end -- ./compiler/lua53.can:151 -local function all(list, tags) -- ./compiler/lua53.can:155 -for _, node in ipairs(list) do -- ./compiler/lua53.can:156 -local ok = false -- ./compiler/lua53.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 -if node["tag"] == tag then -- ./compiler/lua53.can:159 -ok = true -- ./compiler/lua53.can:160 -break -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -if not ok then -- ./compiler/lua53.can:164 -return false -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -return true -- ./compiler/lua53.can:168 -end -- ./compiler/lua53.can:168 -local tags -- ./compiler/lua53.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 -end -- ./compiler/lua53.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 -end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 -end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 -end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- ./compiler/lua53.can:188 -return "do" .. indent() -- ./compiler/lua53.can:189 -end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 -end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 -local vars = {} -- ./compiler/lua53.can:195 -local values = {} -- ./compiler/lua53.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 -for _, v in ipairs(list) do -- ./compiler/lua53.can:198 -local var, val -- ./compiler/lua53.can:199 -if v["tag"] == "Id" then -- ./compiler/lua53.can:200 -var = v -- ./compiler/lua53.can:201 -val = { -- ./compiler/lua53.can:202 -["tag"] = "Index", -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "Id", -- ./compiler/lua53.can:202 -list["id"] -- ./compiler/lua53.can:202 -}, -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "String", -- ./compiler/lua53.can:202 -v[1] -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 -var = v[2] -- ./compiler/lua53.can:204 -val = { -- ./compiler/lua53.can:205 -["tag"] = "Index", -- ./compiler/lua53.can:205 -{ -- ./compiler/lua53.can:205 -["tag"] = "Id", -- ./compiler/lua53.can:205 -list["id"] -- ./compiler/lua53.can:205 -}, -- ./compiler/lua53.can:205 -v[1] -- ./compiler/lua53.can:205 -} -- ./compiler/lua53.can:205 -else -- ./compiler/lua53.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 -end -- ./compiler/lua53.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 -val = { -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["rightOp"], -- ./compiler/lua53.can:210 -var, -- ./compiler/lua53.can:210 -{ -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["leftOp"], -- ./compiler/lua53.can:210 -val, -- ./compiler/lua53.can:210 -var -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 -val = { -- ./compiler/lua53.can:212 -["tag"] = "Op", -- ./compiler/lua53.can:212 -destructured["rightOp"], -- ./compiler/lua53.can:212 -var, -- ./compiler/lua53.can:212 -val -- ./compiler/lua53.can:212 -} -- ./compiler/lua53.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 -val = { -- ./compiler/lua53.can:214 -["tag"] = "Op", -- ./compiler/lua53.can:214 -destructured["leftOp"], -- ./compiler/lua53.can:214 -val, -- ./compiler/lua53.can:214 -var -- ./compiler/lua53.can:214 -} -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -if # vars > 0 then -- ./compiler/lua53.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 -if newlineAfter then -- ./compiler/lua53.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 -else -- ./compiler/lua53.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 -end -- ./compiler/lua53.can:225 -else -- ./compiler/lua53.can:225 -return "" -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -tags = setmetatable({ -- ./compiler/lua53.can:233 -["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 -hasPush = false -- ./compiler/lua53.can:239 -end -- ./compiler/lua53.can:239 -local r = push("scope", {}) -- ./compiler/lua53.can:241 -if hasPush then -- ./compiler/lua53.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 -end -- ./compiler/lua53.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:246 -end -- ./compiler/lua53.can:246 -if t[# t] then -- ./compiler/lua53.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 -end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. pop("scope") -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Do"] = function(t) -- ./compiler/lua53.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 -end, -- ./compiler/lua53.can:261 -["Set"] = function(t) -- ./compiler/lua53.can:264 -local expr = t[# t] -- ./compiler/lua53.can:266 -local vars, values = {}, {} -- ./compiler/lua53.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 -else -- ./compiler/lua53.can:272 -table["insert"](vars, n) -- ./compiler/lua53.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 -local r = "" -- ./compiler/lua53.can:280 -if # vars > 0 then -- ./compiler/lua53.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 -end -- ./compiler/lua53.can:282 -if # destructuringVars > 0 then -- ./compiler/lua53.can:284 -local destructured = {} -- ./compiler/lua53.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 -end -- ./compiler/lua53.can:287 -return r -- ./compiler/lua53.can:289 -elseif # t == 4 then -- ./compiler/lua53.can:290 -if t[3] == "=" then -- ./compiler/lua53.can:291 -local r = "" -- ./compiler/lua53.can:292 -if # vars > 0 then -- ./compiler/lua53.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 -t[2], -- ./compiler/lua53.can:294 -vars[1], -- ./compiler/lua53.can:294 -{ -- ./compiler/lua53.can:294 -["tag"] = "Paren", -- ./compiler/lua53.can:294 -values[1] -- ./compiler/lua53.can:294 -} -- ./compiler/lua53.can:294 -}, "Op")) -- ./compiler/lua53.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 -t[2], -- ./compiler/lua53.can:296 -vars[i], -- ./compiler/lua53.can:296 -{ -- ./compiler/lua53.can:296 -["tag"] = "Paren", -- ./compiler/lua53.can:296 -values[i] -- ./compiler/lua53.can:296 -} -- ./compiler/lua53.can:296 -}, "Op")) -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -if # destructuringVars > 0 then -- ./compiler/lua53.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:302 -end -- ./compiler/lua53.can:302 -return r -- ./compiler/lua53.can:304 -else -- ./compiler/lua53.can:304 -local r = "" -- ./compiler/lua53.can:306 -if # vars > 0 then -- ./compiler/lua53.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 -t[3], -- ./compiler/lua53.can:308 -{ -- ./compiler/lua53.can:308 -["tag"] = "Paren", -- ./compiler/lua53.can:308 -values[1] -- ./compiler/lua53.can:308 -}, -- ./compiler/lua53.can:308 -vars[1] -- ./compiler/lua53.can:308 -}, "Op")) -- ./compiler/lua53.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 -t[3], -- ./compiler/lua53.can:310 -{ -- ./compiler/lua53.can:310 -["tag"] = "Paren", -- ./compiler/lua53.can:310 -values[i] -- ./compiler/lua53.can:310 -}, -- ./compiler/lua53.can:310 -vars[i] -- ./compiler/lua53.can:310 -}, "Op")) -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -if # destructuringVars > 0 then -- ./compiler/lua53.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 -end -- ./compiler/lua53.can:316 -return r -- ./compiler/lua53.can:318 -end -- ./compiler/lua53.can:318 -else -- ./compiler/lua53.can:318 -local r = "" -- ./compiler/lua53.can:321 -if # vars > 0 then -- ./compiler/lua53.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 -t[2], -- ./compiler/lua53.can:323 -vars[1], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Op", -- ./compiler/lua53.can:323 -t[4], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Paren", -- ./compiler/lua53.can:323 -values[1] -- ./compiler/lua53.can:323 -}, -- ./compiler/lua53.can:323 -vars[1] -- ./compiler/lua53.can:323 -} -- ./compiler/lua53.can:323 -}, "Op")) -- ./compiler/lua53.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 -t[2], -- ./compiler/lua53.can:325 -vars[i], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Op", -- ./compiler/lua53.can:325 -t[4], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Paren", -- ./compiler/lua53.can:325 -values[i] -- ./compiler/lua53.can:325 -}, -- ./compiler/lua53.can:325 -vars[i] -- ./compiler/lua53.can:325 -} -- ./compiler/lua53.can:325 -}, "Op")) -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -if # destructuringVars > 0 then -- ./compiler/lua53.can:328 -local destructured = { -- ./compiler/lua53.can:329 -["rightOp"] = t[2], -- ./compiler/lua53.can:329 -["leftOp"] = t[4] -- ./compiler/lua53.can:329 -} -- ./compiler/lua53.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 -end -- ./compiler/lua53.can:331 -return r -- ./compiler/lua53.can:333 -end -- ./compiler/lua53.can:333 -end, -- ./compiler/lua53.can:333 -["While"] = function(t) -- ./compiler/lua53.can:337 -local r = "" -- ./compiler/lua53.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 -if # lets > 0 then -- ./compiler/lua53.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 -if # lets > 0 then -- ./compiler/lua53.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 -end -- ./compiler/lua53.can:349 -if hasContinue then -- ./compiler/lua53.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 -end -- ./compiler/lua53.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 -if hasContinue then -- ./compiler/lua53.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 -end -- ./compiler/lua53.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 -if # lets > 0 then -- ./compiler/lua53.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 -end -- ./compiler/lua53.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 -end -- ./compiler/lua53.can:363 -return r -- ./compiler/lua53.can:365 -end, -- ./compiler/lua53.can:365 -["Repeat"] = function(t) -- ./compiler/lua53.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 -local r = "repeat" .. indent() -- ./compiler/lua53.can:370 -if hasContinue then -- ./compiler/lua53.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 -end -- ./compiler/lua53.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 -if hasContinue then -- ./compiler/lua53.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 -return r -- ./compiler/lua53.can:379 -end, -- ./compiler/lua53.can:379 -["If"] = function(t) -- ./compiler/lua53.can:382 -local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- ./compiler/lua53.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 -if # lets > 0 then -- ./compiler/lua53.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 -toClose = toClose + (1) -- ./compiler/lua53.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 -if # lets > 0 then -- ./compiler/lua53.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 -toClose = toClose + (1) -- ./compiler/lua53.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 -end -- ./compiler/lua53.can:400 -else -- ./compiler/lua53.can:400 -r = r .. ("else") -- ./compiler/lua53.can:403 -end -- ./compiler/lua53.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -if # t % 2 == 1 then -- ./compiler/lua53.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 -end -- ./compiler/lua53.can:408 -r = r .. ("end") -- ./compiler/lua53.can:410 -for i = 1, toClose do -- ./compiler/lua53.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 -end -- ./compiler/lua53.can:412 -return r -- ./compiler/lua53.can:414 -end, -- ./compiler/lua53.can:414 -["Fornum"] = function(t) -- ./compiler/lua53.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 -if # t == 5 then -- ./compiler/lua53.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 -if hasContinue then -- ./compiler/lua53.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 -if hasContinue then -- ./compiler/lua53.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 -end -- ./compiler/lua53.can:427 -return r .. unindent() .. "end" -- ./compiler/lua53.can:429 -else -- ./compiler/lua53.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 -if hasContinue then -- ./compiler/lua53.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 -end -- ./compiler/lua53.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 -if hasContinue then -- ./compiler/lua53.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 -end -- ./compiler/lua53.can:438 -return r .. unindent() .. "end" -- ./compiler/lua53.can:440 -end -- ./compiler/lua53.can:440 -end, -- ./compiler/lua53.can:440 -["Forin"] = function(t) -- ./compiler/lua53.can:444 -local destructured = {} -- ./compiler/lua53.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 -if hasContinue then -- ./compiler/lua53.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 -end -- ./compiler/lua53.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 -if hasContinue then -- ./compiler/lua53.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 -end -- ./compiler/lua53.can:453 -return r .. unindent() .. "end" -- ./compiler/lua53.can:455 -end, -- ./compiler/lua53.can:455 -["Local"] = function(t) -- ./compiler/lua53.can:458 -local destructured = {} -- ./compiler/lua53.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 -if t[2][1] then -- ./compiler/lua53.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 -end -- ./compiler/lua53.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 -end, -- ./compiler/lua53.can:464 -["Let"] = function(t) -- ./compiler/lua53.can:467 -local destructured = {} -- ./compiler/lua53.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 -local r = "local " .. nameList -- ./compiler/lua53.can:470 -if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- ./compiler/lua53.can:472 -"Nil", -- ./compiler/lua53.can:472 -"Dots", -- ./compiler/lua53.can:472 -"Boolean", -- ./compiler/lua53.can:472 -"Number", -- ./compiler/lua53.can:472 -"String" -- ./compiler/lua53.can:472 -}) then -- ./compiler/lua53.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 -else -- ./compiler/lua53.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["Localrec"] = function(t) -- ./compiler/lua53.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["Goto"] = function(t) -- ./compiler/lua53.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["Label"] = function(t) -- ./compiler/lua53.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 -end, -- ./compiler/lua53.can:490 -["Return"] = function(t) -- ./compiler/lua53.can:493 -local push = peek("push") -- ./compiler/lua53.can:494 -if push then -- ./compiler/lua53.can:495 -local r = "" -- ./compiler/lua53.can:496 -for _, val in ipairs(t) do -- ./compiler/lua53.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 -end -- ./compiler/lua53.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 -else -- ./compiler/lua53.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 -end -- ./compiler/lua53.can:502 -end, -- ./compiler/lua53.can:502 -["Push"] = function(t) -- ./compiler/lua53.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 -r = "" -- ./compiler/lua53.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 -end -- ./compiler/lua53.can:510 -if t[# t] then -- ./compiler/lua53.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 -else -- ./compiler/lua53.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -return r -- ./compiler/lua53.can:519 -end, -- ./compiler/lua53.can:519 -["Break"] = function() -- ./compiler/lua53.can:522 -return "break" -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["Continue"] = function() -- ./compiler/lua53.can:526 -return "goto " .. var("continue") -- ./compiler/lua53.can:527 -end, -- ./compiler/lua53.can:527 -["Nil"] = function() -- ./compiler/lua53.can:534 -return "nil" -- ./compiler/lua53.can:535 -end, -- ./compiler/lua53.can:535 -["Dots"] = function() -- ./compiler/lua53.can:538 -return "..." -- ./compiler/lua53.can:539 -end, -- ./compiler/lua53.can:539 -["Boolean"] = function(t) -- ./compiler/lua53.can:542 -return tostring(t[1]) -- ./compiler/lua53.can:543 -end, -- ./compiler/lua53.can:543 -["Number"] = function(t) -- ./compiler/lua53.can:546 -return tostring(t[1]) -- ./compiler/lua53.can:547 -end, -- ./compiler/lua53.can:547 -["String"] = function(t) -- ./compiler/lua53.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 -end, -- ./compiler/lua53.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 -local r = "(" -- ./compiler/lua53.can:555 -local decl = {} -- ./compiler/lua53.can:556 -if t[1][1] then -- ./compiler/lua53.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 -r = r .. (id) -- ./compiler/lua53.can:563 -else -- ./compiler/lua53.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 -end -- ./compiler/lua53.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 -r = r .. (", " .. id) -- ./compiler/lua53.can:573 -else -- ./compiler/lua53.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 -r = r .. (d .. newline()) -- ./compiler/lua53.can:581 -end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 -end -- ./compiler/lua53.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 -if hasPush then -- ./compiler/lua53.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 -else -- ./compiler/lua53.can:588 -push("push", false) -- ./compiler/lua53.can:590 -end -- ./compiler/lua53.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 -end -- ./compiler/lua53.can:594 -pop("push") -- ./compiler/lua53.can:596 -return r .. unindent() .. "end" -- ./compiler/lua53.can:597 -end, -- ./compiler/lua53.can:597 -["Function"] = function(t) -- ./compiler/lua53.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 -end, -- ./compiler/lua53.can:600 -["Pair"] = function(t) -- ./compiler/lua53.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 -end, -- ./compiler/lua53.can:604 -["Table"] = function(t) -- ./compiler/lua53.can:606 -if # t == 0 then -- ./compiler/lua53.can:607 -return "{}" -- ./compiler/lua53.can:608 -elseif # t == 1 then -- ./compiler/lua53.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 -else -- ./compiler/lua53.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 -end -- ./compiler/lua53.can:612 -end, -- ./compiler/lua53.can:612 -["TableCompr"] = function(t) -- ./compiler/lua53.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 -end, -- ./compiler/lua53.can:617 -["Op"] = function(t) -- ./compiler/lua53.can:620 -local r -- ./compiler/lua53.can:621 -if # t == 2 then -- ./compiler/lua53.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 -else -- ./compiler/lua53.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 -end -- ./compiler/lua53.can:626 -else -- ./compiler/lua53.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 -else -- ./compiler/lua53.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -return r -- ./compiler/lua53.can:635 -end, -- ./compiler/lua53.can:635 -["Paren"] = function(t) -- ./compiler/lua53.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 -end, -- ./compiler/lua53.can:639 -["MethodStub"] = function(t) -- ./compiler/lua53.can:642 -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:648 -end, -- ./compiler/lua53.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 -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:658 -end, -- ./compiler/lua53.can:658 -["LetExpr"] = function(t) -- ./compiler/lua53.can:665 -return lua(t[1][1]) -- ./compiler/lua53.can:666 -end, -- ./compiler/lua53.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 -local r = "(function()" .. indent() -- ./compiler/lua53.can:672 -if hasPush then -- ./compiler/lua53.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 -else -- ./compiler/lua53.can:674 -push("push", false) -- ./compiler/lua53.can:676 -end -- ./compiler/lua53.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 -if hasPush then -- ./compiler/lua53.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 -end -- ./compiler/lua53.can:680 -pop("push") -- ./compiler/lua53.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 -return r -- ./compiler/lua53.can:684 -end, -- ./compiler/lua53.can:684 -["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 -end -- ./compiler/lua53.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 -end, -- ./compiler/lua53.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 -end, -- ./compiler/lua53.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 -end, -- ./compiler/lua53.can:699 -["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- ./compiler/lua53.can:703 -local block = t[i] -- ./compiler/lua53.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 -end, -- ./compiler/lua53.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 -end, -- ./compiler/lua53.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 -end, -- ./compiler/lua53.can:717 -["Call"] = function(t) -- ./compiler/lua53.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 -else -- ./compiler/lua53.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 -end -- ./compiler/lua53.can:730 -else -- ./compiler/lua53.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 -end -- ./compiler/lua53.can:733 -end, -- ./compiler/lua53.can:733 -["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 -else -- ./compiler/lua53.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 -end -- ./compiler/lua53.can:741 -end, -- ./compiler/lua53.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 -if start == nil then start = 1 end -- ./compiler/lua53.can:746 -local r -- ./compiler/lua53.can:747 -if t[start] then -- ./compiler/lua53.can:748 -r = lua(t[start]) -- ./compiler/lua53.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 -end -- ./compiler/lua53.can:751 -else -- ./compiler/lua53.can:751 -r = "" -- ./compiler/lua53.can:754 -end -- ./compiler/lua53.can:754 -return r -- ./compiler/lua53.can:756 -end, -- ./compiler/lua53.can:756 -["Id"] = function(t) -- ./compiler/lua53.can:759 -return t[1] -- ./compiler/lua53.can:760 -end, -- ./compiler/lua53.can:760 -["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- ./compiler/lua53.can:764 -return t["id"] -- ./compiler/lua53.can:765 -else -- ./compiler/lua53.can:765 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 -local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 -for j = 1, # t, 1 do -- ./compiler/lua53.can:769 -table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 -end -- ./compiler/lua53.can:770 -table["insert"](d, vars) -- ./compiler/lua53.can:772 -t["id"] = vars["id"] -- ./compiler/lua53.can:773 -return vars["id"] -- ./compiler/lua53.can:774 -end -- ./compiler/lua53.can:774 -end, -- ./compiler/lua53.can:774 -["Index"] = function(t) -- ./compiler/lua53.can:778 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 -else -- ./compiler/lua53.can:780 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 -end -- ./compiler/lua53.can:782 -end, -- ./compiler/lua53.can:782 -["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 -local l = {} -- ./compiler/lua53.can:788 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 -table["insert"](l, 1, t) -- ./compiler/lua53.can:790 -t = t[1] -- ./compiler/lua53.can:791 -end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 -for _, e in ipairs(l) do -- ./compiler/lua53.can:794 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 -if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 -else -- ./compiler/lua53.can:797 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 -return r -- ./compiler/lua53.can:803 -else -- ./compiler/lua53.can:803 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 -end -- ./compiler/lua53.can:805 -end, -- ./compiler/lua53.can:805 -["_opid"] = { -- ./compiler/lua53.can:810 -["add"] = "+", -- ./compiler/lua53.can:811 -["sub"] = "-", -- ./compiler/lua53.can:811 -["mul"] = "*", -- ./compiler/lua53.can:811 -["div"] = "/", -- ./compiler/lua53.can:811 -["idiv"] = "//", -- ./compiler/lua53.can:812 -["mod"] = "%", -- ./compiler/lua53.can:812 -["pow"] = "^", -- ./compiler/lua53.can:812 -["concat"] = "..", -- ./compiler/lua53.can:812 -["band"] = "&", -- ./compiler/lua53.can:813 -["bor"] = "|", -- ./compiler/lua53.can:813 -["bxor"] = "~", -- ./compiler/lua53.can:813 -["shl"] = "<<", -- ./compiler/lua53.can:813 -["shr"] = ">>", -- ./compiler/lua53.can:813 -["eq"] = "==", -- ./compiler/lua53.can:814 -["ne"] = "~=", -- ./compiler/lua53.can:814 -["lt"] = "<", -- ./compiler/lua53.can:814 -["gt"] = ">", -- ./compiler/lua53.can:814 -["le"] = "<=", -- ./compiler/lua53.can:814 -["ge"] = ">=", -- ./compiler/lua53.can:814 -["and"] = "and", -- ./compiler/lua53.can:815 -["or"] = "or", -- ./compiler/lua53.can:815 -["unm"] = "-", -- ./compiler/lua53.can:815 -["len"] = "#", -- ./compiler/lua53.can:815 -["bnot"] = "~", -- ./compiler/lua53.can:815 -["not"] = "not" -- ./compiler/lua53.can:815 -} -- ./compiler/lua53.can:815 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 -end }) -- ./compiler/lua53.can:819 -local code = lua(ast) .. newline() -- ./compiler/lua53.can:825 -return requireStr .. code -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -local lua53 = _() or lua53 -- ./compiler/lua53.can:831 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:832 -local function _() -- ./compiler/lua53.can:835 -local function _() -- ./compiler/lua53.can:837 -local targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -return function(code, ast, options) -- ./compiler/lua53.can:3 -local lastInputPos = 1 -- ./compiler/lua53.can:5 -local prevLinePos = 1 -- ./compiler/lua53.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 -local lastLine = 1 -- ./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 +") do -- ./compiler/lua54.can:23 +lastLine = lastLine + (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +prevLinePos = lastInputPos -- ./compiler/lua54.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 +end -- ./compiler/lua54.can:30 +return r -- ./compiler/lua54.can:32 +end -- ./compiler/lua54.can:32 +local function indent() -- ./compiler/lua54.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 +return newline() -- ./compiler/lua54.can:37 +end -- ./compiler/lua54.can:37 +local function unindent() -- ./compiler/lua54.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 +return newline() -- ./compiler/lua54.can:42 +end -- ./compiler/lua54.can:42 +local states = { -- ./compiler/lua54.can:47 +["push"] = {}, -- ./compiler/lua54.can:48 +["destructuring"] = {}, -- ./compiler/lua54.can:49 +["scope"] = {} -- ./compiler/lua54.can:50 +} -- ./compiler/lua54.can:50 +local function push(name, state) -- ./compiler/lua54.can:53 +table["insert"](states[name], state) -- ./compiler/lua54.can:54 +return "" -- ./compiler/lua54.can:55 +end -- ./compiler/lua54.can:55 +local function pop(name) -- ./compiler/lua54.can:58 +table["remove"](states[name]) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function set(name, state) -- ./compiler/lua54.can:63 +states[name][# states[name]] = state -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function peek(name) -- ./compiler/lua54.can:68 +return states[name][# states[name]] -- ./compiler/lua54.can:69 +end -- ./compiler/lua54.can:69 +local function var(name) -- ./compiler/lua54.can:74 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 +end -- ./compiler/lua54.can:75 +local function tmp() -- ./compiler/lua54.can:79 +local scope = peek("scope") -- ./compiler/lua54.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 +table["insert"](scope, var) -- ./compiler/lua54.can:82 +return var -- ./compiler/lua54.can:83 +end -- ./compiler/lua54.can:83 +local required = {} -- ./compiler/lua54.can:87 +local requireStr = "" -- ./compiler/lua54.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 +if not required[req] then -- ./compiler/lua54.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 +required[req] = true -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +local loop = { -- ./compiler/lua54.can:99 +"While", -- ./compiler/lua54.can:99 +"Repeat", -- ./compiler/lua54.can:99 +"Fornum", -- ./compiler/lua54.can:99 +"Forin", -- ./compiler/lua54.can:99 +"WhileExpr", -- ./compiler/lua54.can:99 +"RepeatExpr", -- ./compiler/lua54.can:99 +"FornumExpr", -- ./compiler/lua54.can:99 +"ForinExpr" -- ./compiler/lua54.can:99 +} -- ./compiler/lua54.can:99 +local func = { -- ./compiler/lua54.can:100 +"Function", -- ./compiler/lua54.can:100 +"TableCompr", -- ./compiler/lua54.can:100 +"DoExpr", -- ./compiler/lua54.can:100 +"WhileExpr", -- ./compiler/lua54.can:100 +"RepeatExpr", -- ./compiler/lua54.can:100 +"IfExpr", -- ./compiler/lua54.can:100 +"FornumExpr", -- ./compiler/lua54.can:100 +"ForinExpr" -- ./compiler/lua54.can:100 +} -- ./compiler/lua54.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 +local tagsCheck = {} -- ./compiler/lua54.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 +tagsCheck[tag] = true -- ./compiler/lua54.can:107 +end -- ./compiler/lua54.can:107 +local nofollowCheck = {} -- ./compiler/lua54.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 +nofollowCheck[tag] = true -- ./compiler/lua54.can:111 +end -- ./compiler/lua54.can:111 +for _, node in ipairs(list) do -- ./compiler/lua54.can:113 +if type(node) == "table" then -- ./compiler/lua54.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 +return node -- ./compiler/lua54.can:116 +end -- ./compiler/lua54.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 +if r then -- ./compiler/lua54.can:120 +return r -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +return nil -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 +local tagsCheck = {} -- ./compiler/lua54.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 +tagsCheck[tag] = true -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local nofollowCheck = {} -- ./compiler/lua54.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 +nofollowCheck[tag] = true -- ./compiler/lua54.can:136 +end -- ./compiler/lua54.can:136 +local found = {} -- ./compiler/lua54.can:138 +for _, node in ipairs(list) do -- ./compiler/lua54.can:139 +if type(node) == "table" then -- ./compiler/lua54.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 +table["insert"](found, n) -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 +table["insert"](found, node) -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +return found -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +local function all(list, tags) -- ./compiler/lua54.can:155 +for _, node in ipairs(list) do -- ./compiler/lua54.can:156 +local ok = false -- ./compiler/lua54.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 +if node["tag"] == tag then -- ./compiler/lua54.can:159 +ok = true -- ./compiler/lua54.can:160 +break -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +if not ok then -- ./compiler/lua54.can:164 +return false -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +return true -- ./compiler/lua54.can:168 +end -- ./compiler/lua54.can:168 +local tags -- ./compiler/lua54.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 +end -- ./compiler/lua54.can:178 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 +end -- ./compiler/lua54.can:183 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local CONTINUE_START = function() -- ./compiler/lua54.can:188 +return "do" .. indent() -- ./compiler/lua54.can:189 +end -- ./compiler/lua54.can:189 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +end -- ./compiler/lua54.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 +local vars = {} -- ./compiler/lua54.can:195 +local values = {} -- ./compiler/lua54.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 +for _, v in ipairs(list) do -- ./compiler/lua54.can:198 +local var, val -- ./compiler/lua54.can:199 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 +var = v -- ./compiler/lua54.can:201 +val = { -- ./compiler/lua54.can:202 +["tag"] = "Index", -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "Id", -- ./compiler/lua54.can:202 +list["id"] -- ./compiler/lua54.can:202 +}, -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "String", -- ./compiler/lua54.can:202 +v[1] -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 +var = v[2] -- ./compiler/lua54.can:204 +val = { -- ./compiler/lua54.can:205 +["tag"] = "Index", -- ./compiler/lua54.can:205 +{ -- ./compiler/lua54.can:205 +["tag"] = "Id", -- ./compiler/lua54.can:205 +list["id"] -- ./compiler/lua54.can:205 +}, -- ./compiler/lua54.can:205 +v[1] -- ./compiler/lua54.can:205 +} -- ./compiler/lua54.can:205 +else -- ./compiler/lua54.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 +end -- ./compiler/lua54.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["rightOp"], -- ./compiler/lua54.can:210 +var, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["leftOp"], -- ./compiler/lua54.can:210 +val, -- ./compiler/lua54.can:210 +var -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 +val = { -- ./compiler/lua54.can:212 +["tag"] = "Op", -- ./compiler/lua54.can:212 +destructured["rightOp"], -- ./compiler/lua54.can:212 +var, -- ./compiler/lua54.can:212 +val -- ./compiler/lua54.can:212 +} -- ./compiler/lua54.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 +val = { -- ./compiler/lua54.can:214 +["tag"] = "Op", -- ./compiler/lua54.can:214 +destructured["leftOp"], -- ./compiler/lua54.can:214 +val, -- ./compiler/lua54.can:214 +var -- ./compiler/lua54.can:214 +} -- ./compiler/lua54.can:214 +end -- ./compiler/lua54.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +if # vars > 0 then -- ./compiler/lua54.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 +if newlineAfter then -- ./compiler/lua54.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 +else -- ./compiler/lua54.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +else -- ./compiler/lua54.can:225 +return "" -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +tags = setmetatable({ -- ./compiler/lua54.can:233 +["Block"] = function(t) -- ./compiler/lua54.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 +hasPush = false -- ./compiler/lua54.can:239 +end -- ./compiler/lua54.can:239 +local r = push("scope", {}) -- ./compiler/lua54.can:241 +if hasPush then -- ./compiler/lua54.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 +end -- ./compiler/lua54.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 +end -- ./compiler/lua54.can:246 +if t[# t] then -- ./compiler/lua54.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +end -- ./compiler/lua54.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +end -- ./compiler/lua54.can:252 +return r .. pop("scope") -- ./compiler/lua54.can:254 +end, -- ./compiler/lua54.can:254 +["Do"] = function(t) -- ./compiler/lua54.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 +end, -- ./compiler/lua54.can:261 +["Set"] = function(t) -- ./compiler/lua54.can:264 +local expr = t[# t] -- ./compiler/lua54.can:266 +local vars, values = {}, {} -- ./compiler/lua54.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 +else -- ./compiler/lua54.can:272 +table["insert"](vars, n) -- ./compiler/lua54.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 +local r = "" -- ./compiler/lua54.can:280 +if # vars > 0 then -- ./compiler/lua54.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 +end -- ./compiler/lua54.can:282 +if # destructuringVars > 0 then -- ./compiler/lua54.can:284 +local destructured = {} -- ./compiler/lua54.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 +end -- ./compiler/lua54.can:287 +return r -- ./compiler/lua54.can:289 +elseif # t == 4 then -- ./compiler/lua54.can:290 +if t[3] == "=" then -- ./compiler/lua54.can:291 +local r = "" -- ./compiler/lua54.can:292 +if # vars > 0 then -- ./compiler/lua54.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 +t[2], -- ./compiler/lua54.can:294 +vars[1], -- ./compiler/lua54.can:294 +{ -- ./compiler/lua54.can:294 +["tag"] = "Paren", -- ./compiler/lua54.can:294 +values[1] -- ./compiler/lua54.can:294 +} -- ./compiler/lua54.can:294 +}, "Op")) -- ./compiler/lua54.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 +t[2], -- ./compiler/lua54.can:296 +vars[i], -- ./compiler/lua54.can:296 +{ -- ./compiler/lua54.can:296 +["tag"] = "Paren", -- ./compiler/lua54.can:296 +values[i] -- ./compiler/lua54.can:296 +} -- ./compiler/lua54.can:296 +}, "Op")) -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +if # destructuringVars > 0 then -- ./compiler/lua54.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +end -- ./compiler/lua54.can:302 +return r -- ./compiler/lua54.can:304 +else -- ./compiler/lua54.can:304 +local r = "" -- ./compiler/lua54.can:306 +if # vars > 0 then -- ./compiler/lua54.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 +t[3], -- ./compiler/lua54.can:308 +{ -- ./compiler/lua54.can:308 +["tag"] = "Paren", -- ./compiler/lua54.can:308 +values[1] -- ./compiler/lua54.can:308 +}, -- ./compiler/lua54.can:308 +vars[1] -- ./compiler/lua54.can:308 +}, "Op")) -- ./compiler/lua54.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 +t[3], -- ./compiler/lua54.can:310 +{ -- ./compiler/lua54.can:310 +["tag"] = "Paren", -- ./compiler/lua54.can:310 +values[i] -- ./compiler/lua54.can:310 +}, -- ./compiler/lua54.can:310 +vars[i] -- ./compiler/lua54.can:310 +}, "Op")) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +if # destructuringVars > 0 then -- ./compiler/lua54.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:316 +return r -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +else -- ./compiler/lua54.can:318 +local r = "" -- ./compiler/lua54.can:321 +if # vars > 0 then -- ./compiler/lua54.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 +t[2], -- ./compiler/lua54.can:323 +vars[1], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Op", -- ./compiler/lua54.can:323 +t[4], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Paren", -- ./compiler/lua54.can:323 +values[1] -- ./compiler/lua54.can:323 +}, -- ./compiler/lua54.can:323 +vars[1] -- ./compiler/lua54.can:323 +} -- ./compiler/lua54.can:323 +}, "Op")) -- ./compiler/lua54.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 +t[2], -- ./compiler/lua54.can:325 +vars[i], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Op", -- ./compiler/lua54.can:325 +t[4], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Paren", -- ./compiler/lua54.can:325 +values[i] -- ./compiler/lua54.can:325 +}, -- ./compiler/lua54.can:325 +vars[i] -- ./compiler/lua54.can:325 +} -- ./compiler/lua54.can:325 +}, "Op")) -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +if # destructuringVars > 0 then -- ./compiler/lua54.can:328 +local destructured = { -- ./compiler/lua54.can:329 +["rightOp"] = t[2], -- ./compiler/lua54.can:329 +["leftOp"] = t[4] -- ./compiler/lua54.can:329 +} -- ./compiler/lua54.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +end -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end, -- ./compiler/lua54.can:333 +["While"] = function(t) -- ./compiler/lua54.can:337 +local r = "" -- ./compiler/lua54.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 +if # lets > 0 then -- ./compiler/lua54.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 +if # lets > 0 then -- ./compiler/lua54.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 +end -- ./compiler/lua54.can:349 +if hasContinue then -- ./compiler/lua54.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 +if hasContinue then -- ./compiler/lua54.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 +end -- ./compiler/lua54.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 +if # lets > 0 then -- ./compiler/lua54.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 +end -- ./compiler/lua54.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 +end -- ./compiler/lua54.can:363 +return r -- ./compiler/lua54.can:365 +end, -- ./compiler/lua54.can:365 +["Repeat"] = function(t) -- ./compiler/lua54.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 +local r = "repeat" .. indent() -- ./compiler/lua54.can:370 +if hasContinue then -- ./compiler/lua54.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 +end -- ./compiler/lua54.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 +if hasContinue then -- ./compiler/lua54.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 +end -- ./compiler/lua54.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 +return r -- ./compiler/lua54.can:379 +end, -- ./compiler/lua54.can:379 +["If"] = function(t) -- ./compiler/lua54.can:382 +local r = "" -- ./compiler/lua54.can:383 +local toClose = 0 -- ./compiler/lua54.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 +if # lets > 0 then -- ./compiler/lua54.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 +toClose = toClose + (1) -- ./compiler/lua54.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 +if # lets > 0 then -- ./compiler/lua54.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 +toClose = toClose + (1) -- ./compiler/lua54.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 +end -- ./compiler/lua54.can:400 +else -- ./compiler/lua54.can:400 +r = r .. ("else") -- ./compiler/lua54.can:403 +end -- ./compiler/lua54.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 +end -- ./compiler/lua54.can:405 +if # t % 2 == 1 then -- ./compiler/lua54.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +r = r .. ("end") -- ./compiler/lua54.can:410 +for i = 1, toClose do -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 +end -- ./compiler/lua54.can:412 +return r -- ./compiler/lua54.can:414 +end, -- ./compiler/lua54.can:414 +["Fornum"] = function(t) -- ./compiler/lua54.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 +if # t == 5 then -- ./compiler/lua54.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 +if hasContinue then -- ./compiler/lua54.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 +end -- ./compiler/lua54.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 +if hasContinue then -- ./compiler/lua54.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 +end -- ./compiler/lua54.can:427 +return r .. unindent() .. "end" -- ./compiler/lua54.can:429 +else -- ./compiler/lua54.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 +if hasContinue then -- ./compiler/lua54.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 +end -- ./compiler/lua54.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 +if hasContinue then -- ./compiler/lua54.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 +end -- ./compiler/lua54.can:438 +return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:440 +end, -- ./compiler/lua54.can:440 +["Forin"] = function(t) -- ./compiler/lua54.can:444 +local destructured = {} -- ./compiler/lua54.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 +if hasContinue then -- ./compiler/lua54.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 +end -- ./compiler/lua54.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 +if hasContinue then -- ./compiler/lua54.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 +end -- ./compiler/lua54.can:453 +return r .. unindent() .. "end" -- ./compiler/lua54.can:455 +end, -- ./compiler/lua54.can:455 +["Local"] = function(t) -- ./compiler/lua54.can:458 +local destructured = {} -- ./compiler/lua54.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 +if t[2][1] then -- ./compiler/lua54.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 +end -- ./compiler/lua54.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 +end, -- ./compiler/lua54.can:464 +["Let"] = function(t) -- ./compiler/lua54.can:467 +local destructured = {} -- ./compiler/lua54.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 +local r = "local " .. nameList -- ./compiler/lua54.can:470 +if t[2][1] then -- ./compiler/lua54.can:471 +if all(t[2], { -- ./compiler/lua54.can:472 +"Nil", -- ./compiler/lua54.can:472 +"Dots", -- ./compiler/lua54.can:472 +"Boolean", -- ./compiler/lua54.can:472 +"Number", -- ./compiler/lua54.can:472 +"String" -- ./compiler/lua54.can:472 +}) then -- ./compiler/lua54.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 +else -- ./compiler/lua54.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 +end, -- ./compiler/lua54.can:478 +["Localrec"] = function(t) -- ./compiler/lua54.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 +end, -- ./compiler/lua54.can:482 +["Goto"] = function(t) -- ./compiler/lua54.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Label"] = function(t) -- ./compiler/lua54.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Return"] = function(t) -- ./compiler/lua54.can:493 +local push = peek("push") -- ./compiler/lua54.can:494 +if push then -- ./compiler/lua54.can:495 +local r = "" -- ./compiler/lua54.can:496 +for _, val in ipairs(t) do -- ./compiler/lua54.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 +end -- ./compiler/lua54.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 +else -- ./compiler/lua54.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 +end -- ./compiler/lua54.can:502 +end, -- ./compiler/lua54.can:502 +["Push"] = function(t) -- ./compiler/lua54.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 +r = "" -- ./compiler/lua54.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +if t[# t] then -- ./compiler/lua54.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 +else -- ./compiler/lua54.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +return r -- ./compiler/lua54.can:519 +end, -- ./compiler/lua54.can:519 +["Break"] = function() -- ./compiler/lua54.can:522 +return "break" -- ./compiler/lua54.can:523 +end, -- ./compiler/lua54.can:523 +["Continue"] = function() -- ./compiler/lua54.can:526 +return "goto " .. var("continue") -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Nil"] = function() -- ./compiler/lua54.can:534 +return "nil" -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Dots"] = function() -- ./compiler/lua54.can:538 +return "..." -- ./compiler/lua54.can:539 +end, -- ./compiler/lua54.can:539 +["Boolean"] = function(t) -- ./compiler/lua54.can:542 +return tostring(t[1]) -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Number"] = function(t) -- ./compiler/lua54.can:546 +return tostring(t[1]) -- ./compiler/lua54.can:547 +end, -- ./compiler/lua54.can:547 +["String"] = function(t) -- ./compiler/lua54.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 +end, -- ./compiler/lua54.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 +local r = "(" -- ./compiler/lua54.can:555 +local decl = {} -- ./compiler/lua54.can:556 +if t[1][1] then -- ./compiler/lua54.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 +r = r .. (id) -- ./compiler/lua54.can:563 +else -- ./compiler/lua54.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 +end -- ./compiler/lua54.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 +r = r .. (", " .. id) -- ./compiler/lua54.can:573 +else -- ./compiler/lua54.can:573 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 +r = r .. (d .. newline()) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 +end -- ./compiler/lua54.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 +if hasPush then -- ./compiler/lua54.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 +else -- ./compiler/lua54.can:588 +push("push", false) -- ./compiler/lua54.can:590 +end -- ./compiler/lua54.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 +end -- ./compiler/lua54.can:594 +pop("push") -- ./compiler/lua54.can:596 +return r .. unindent() .. "end" -- ./compiler/lua54.can:597 +end, -- ./compiler/lua54.can:597 +["Function"] = function(t) -- ./compiler/lua54.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 +end, -- ./compiler/lua54.can:600 +["Pair"] = function(t) -- ./compiler/lua54.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 +end, -- ./compiler/lua54.can:604 +["Table"] = function(t) -- ./compiler/lua54.can:606 +if # t == 0 then -- ./compiler/lua54.can:607 +return "{}" -- ./compiler/lua54.can:608 +elseif # t == 1 then -- ./compiler/lua54.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 +else -- ./compiler/lua54.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 +end -- ./compiler/lua54.can:612 +end, -- ./compiler/lua54.can:612 +["TableCompr"] = function(t) -- ./compiler/lua54.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 +end, -- ./compiler/lua54.can:617 +["Op"] = function(t) -- ./compiler/lua54.can:620 +local r -- ./compiler/lua54.can:621 +if # t == 2 then -- ./compiler/lua54.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +else -- ./compiler/lua54.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +end -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 +else -- ./compiler/lua54.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +return r -- ./compiler/lua54.can:635 +end, -- ./compiler/lua54.can:635 +["Paren"] = function(t) -- ./compiler/lua54.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 +end, -- ./compiler/lua54.can:639 +["MethodStub"] = function(t) -- ./compiler/lua54.can:642 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 +end, -- ./compiler/lua54.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 +end, -- ./compiler/lua54.can:658 +["LetExpr"] = function(t) -- ./compiler/lua54.can:665 +return lua(t[1][1]) -- ./compiler/lua54.can:666 +end, -- ./compiler/lua54.can:666 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 +local r = "(function()" .. indent() -- ./compiler/lua54.can:672 +if hasPush then -- ./compiler/lua54.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 +else -- ./compiler/lua54.can:674 +push("push", false) -- ./compiler/lua54.can:676 +end -- ./compiler/lua54.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 +if hasPush then -- ./compiler/lua54.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 +end -- ./compiler/lua54.can:680 +pop("push") -- ./compiler/lua54.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 +return r -- ./compiler/lua54.can:684 +end, -- ./compiler/lua54.can:684 +["DoExpr"] = function(t) -- ./compiler/lua54.can:687 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 +end -- ./compiler/lua54.can:689 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 +end, -- ./compiler/lua54.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 +end, -- ./compiler/lua54.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 +end, -- ./compiler/lua54.can:699 +["IfExpr"] = function(t) -- ./compiler/lua54.can:702 +for i = 2, # t do -- ./compiler/lua54.can:703 +local block = t[i] -- ./compiler/lua54.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +end, -- ./compiler/lua54.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 +end, -- ./compiler/lua54.can:717 +["Call"] = function(t) -- ./compiler/lua54.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 +else -- ./compiler/lua54.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 +end -- ./compiler/lua54.can:730 +else -- ./compiler/lua54.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 +end -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["SafeCall"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 +else -- ./compiler/lua54.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 +end -- ./compiler/lua54.can:741 +end, -- ./compiler/lua54.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 +if start == nil then start = 1 end -- ./compiler/lua54.can:746 +local r -- ./compiler/lua54.can:747 +if t[start] then -- ./compiler/lua54.can:748 +r = lua(t[start]) -- ./compiler/lua54.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 +end -- ./compiler/lua54.can:751 +else -- ./compiler/lua54.can:751 +r = "" -- ./compiler/lua54.can:754 +end -- ./compiler/lua54.can:754 +return r -- ./compiler/lua54.can:756 +end, -- ./compiler/lua54.can:756 +["Id"] = function(t) -- ./compiler/lua54.can:759 +return t[1] -- ./compiler/lua54.can:760 +end, -- ./compiler/lua54.can:760 +["AttributeId"] = function(t) -- ./compiler/lua54.can:763 +if t[2] then -- ./compiler/lua54.can:764 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 +else -- ./compiler/lua54.can:765 +return t[1] -- ./compiler/lua54.can:767 +end -- ./compiler/lua54.can:767 +end, -- ./compiler/lua54.can:767 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 +if t["id"] then -- ./compiler/lua54.can:772 +return t["id"] -- ./compiler/lua54.can:773 +else -- ./compiler/lua54.can:773 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 +for j = 1, # t, 1 do -- ./compiler/lua54.can:777 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 +end -- ./compiler/lua54.can:778 +table["insert"](d, vars) -- ./compiler/lua54.can:780 +t["id"] = vars["id"] -- ./compiler/lua54.can:781 +return vars["id"] -- ./compiler/lua54.can:782 +end -- ./compiler/lua54.can:782 +end, -- ./compiler/lua54.can:782 +["Index"] = function(t) -- ./compiler/lua54.can:786 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 +else -- ./compiler/lua54.can:788 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +end -- ./compiler/lua54.can:790 +end, -- ./compiler/lua54.can:790 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 +local l = {} -- ./compiler/lua54.can:796 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 +table["insert"](l, 1, t) -- ./compiler/lua54.can:798 +t = t[1] -- ./compiler/lua54.can:799 +end -- ./compiler/lua54.can:799 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 +for _, e in ipairs(l) do -- ./compiler/lua54.can:802 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 +else -- ./compiler/lua54.can:805 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 +return r -- ./compiler/lua54.can:811 +else -- ./compiler/lua54.can:811 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 +end -- ./compiler/lua54.can:813 +end, -- ./compiler/lua54.can:813 +["_opid"] = { -- ./compiler/lua54.can:818 +["add"] = "+", -- ./compiler/lua54.can:819 +["sub"] = "-", -- ./compiler/lua54.can:819 +["mul"] = "*", -- ./compiler/lua54.can:819 +["div"] = "/", -- ./compiler/lua54.can:819 +["idiv"] = "//", -- ./compiler/lua54.can:820 +["mod"] = "%", -- ./compiler/lua54.can:820 +["pow"] = "^", -- ./compiler/lua54.can:820 +["concat"] = "..", -- ./compiler/lua54.can:820 +["band"] = "&", -- ./compiler/lua54.can:821 +["bor"] = "|", -- ./compiler/lua54.can:821 +["bxor"] = "~", -- ./compiler/lua54.can:821 +["shl"] = "<<", -- ./compiler/lua54.can:821 +["shr"] = ">>", -- ./compiler/lua54.can:821 +["eq"] = "==", -- ./compiler/lua54.can:822 +["ne"] = "~=", -- ./compiler/lua54.can:822 +["lt"] = "<", -- ./compiler/lua54.can:822 +["gt"] = ">", -- ./compiler/lua54.can:822 +["le"] = "<=", -- ./compiler/lua54.can:822 +["ge"] = ">=", -- ./compiler/lua54.can:822 +["and"] = "and", -- ./compiler/lua54.can:823 +["or"] = "or", -- ./compiler/lua54.can:823 +["unm"] = "-", -- ./compiler/lua54.can:823 +["len"] = "#", -- ./compiler/lua54.can:823 +["bnot"] = "~", -- ./compiler/lua54.can:823 +["not"] = "not" -- ./compiler/lua54.can:823 +} -- ./compiler/lua54.can:823 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 +end }) -- ./compiler/lua54.can:827 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 +return requireStr .. code -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:840 +local function _() -- ./compiler/lua54.can:843 +local function _() -- ./compiler/lua54.can:845 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +return function(code, ast, options) -- ./compiler/lua54.can:3 +local lastInputPos = 1 -- ./compiler/lua54.can:5 +local prevLinePos = 1 -- ./compiler/lua54.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 +local lastLine = 1 -- ./compiler/lua54.can:8 +local indentLevel = 0 -- ./compiler/lua54.can:11 +local function newline() -- ./compiler/lua54.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 +if options["mapLines"] then -- ./compiler/lua54.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./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 +") -- ./compiler/lua54.can:17 +if source and line then -- ./compiler/lua54.can:19 +lastSource = source -- ./compiler/lua54.can:20 +lastLine = tonumber(line) -- ./compiler/lua54.can:21 +else -- ./compiler/lua54.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") 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 -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 states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- ./compiler/lua53.can:49 -["scope"] = {} -- ./compiler/lua53.can:50 -} -- ./compiler/lua53.can:50 -local function push(name, state) -- ./compiler/lua53.can:53 -table["insert"](states[name], state) -- ./compiler/lua53.can:54 -return "" -- ./compiler/lua53.can:55 -end -- ./compiler/lua53.can:55 -local function pop(name) -- ./compiler/lua53.can:58 -table["remove"](states[name]) -- ./compiler/lua53.can:59 -return "" -- ./compiler/lua53.can:60 -end -- ./compiler/lua53.can:60 -local function set(name, state) -- ./compiler/lua53.can:63 -states[name][# states[name]] = state -- ./compiler/lua53.can:64 -return "" -- ./compiler/lua53.can:65 -end -- ./compiler/lua53.can:65 -local function peek(name) -- ./compiler/lua53.can:68 -return states[name][# states[name]] -- ./compiler/lua53.can:69 -end -- ./compiler/lua53.can:69 -local function var(name) -- ./compiler/lua53.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:75 -end -- ./compiler/lua53.can:75 -local function tmp() -- ./compiler/lua53.can:79 -local scope = peek("scope") -- ./compiler/lua53.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 -table["insert"](scope, var) -- ./compiler/lua53.can:82 -return var -- ./compiler/lua53.can:83 -end -- ./compiler/lua53.can:83 -local required = {} -- ./compiler/lua53.can:87 -local requireStr = "" -- ./compiler/lua53.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 -if not required[req] then -- ./compiler/lua53.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 -required[req] = true -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -local loop = { -- ./compiler/lua53.can:99 -"While", -- ./compiler/lua53.can:99 -"Repeat", -- ./compiler/lua53.can:99 -"Fornum", -- ./compiler/lua53.can:99 -"Forin", -- ./compiler/lua53.can:99 -"WhileExpr", -- ./compiler/lua53.can:99 -"RepeatExpr", -- ./compiler/lua53.can:99 -"FornumExpr", -- ./compiler/lua53.can:99 -"ForinExpr" -- ./compiler/lua53.can:99 -} -- ./compiler/lua53.can:99 -local func = { -- ./compiler/lua53.can:100 -"Function", -- ./compiler/lua53.can:100 -"TableCompr", -- ./compiler/lua53.can:100 -"DoExpr", -- ./compiler/lua53.can:100 -"WhileExpr", -- ./compiler/lua53.can:100 -"RepeatExpr", -- ./compiler/lua53.can:100 -"IfExpr", -- ./compiler/lua53.can:100 -"FornumExpr", -- ./compiler/lua53.can:100 -"ForinExpr" -- ./compiler/lua53.can:100 -} -- ./compiler/lua53.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 -local tagsCheck = {} -- ./compiler/lua53.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 -tagsCheck[tag] = true -- ./compiler/lua53.can:107 -end -- ./compiler/lua53.can:107 -local nofollowCheck = {} -- ./compiler/lua53.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 -nofollowCheck[tag] = true -- ./compiler/lua53.can:111 -end -- ./compiler/lua53.can:111 -for _, node in ipairs(list) do -- ./compiler/lua53.can:113 -if type(node) == "table" then -- ./compiler/lua53.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 -return node -- ./compiler/lua53.can:116 -end -- ./compiler/lua53.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 -if r then -- ./compiler/lua53.can:120 -return r -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -return nil -- ./compiler/lua53.can:124 -end -- ./compiler/lua53.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 -local tagsCheck = {} -- ./compiler/lua53.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 -tagsCheck[tag] = true -- ./compiler/lua53.can:132 -end -- ./compiler/lua53.can:132 -local nofollowCheck = {} -- ./compiler/lua53.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 -nofollowCheck[tag] = true -- ./compiler/lua53.can:136 -end -- ./compiler/lua53.can:136 -local found = {} -- ./compiler/lua53.can:138 -for _, node in ipairs(list) do -- ./compiler/lua53.can:139 -if type(node) == "table" then -- ./compiler/lua53.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 -table["insert"](found, n) -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 -table["insert"](found, node) -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -return found -- ./compiler/lua53.can:151 -end -- ./compiler/lua53.can:151 -local function all(list, tags) -- ./compiler/lua53.can:155 -for _, node in ipairs(list) do -- ./compiler/lua53.can:156 -local ok = false -- ./compiler/lua53.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 -if node["tag"] == tag then -- ./compiler/lua53.can:159 -ok = true -- ./compiler/lua53.can:160 -break -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -if not ok then -- ./compiler/lua53.can:164 -return false -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -return true -- ./compiler/lua53.can:168 -end -- ./compiler/lua53.can:168 -local tags -- ./compiler/lua53.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 -end -- ./compiler/lua53.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 -end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 -end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 -end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- ./compiler/lua53.can:188 -return "do" .. indent() -- ./compiler/lua53.can:189 -end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 -end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 -local vars = {} -- ./compiler/lua53.can:195 -local values = {} -- ./compiler/lua53.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 -for _, v in ipairs(list) do -- ./compiler/lua53.can:198 -local var, val -- ./compiler/lua53.can:199 -if v["tag"] == "Id" then -- ./compiler/lua53.can:200 -var = v -- ./compiler/lua53.can:201 -val = { -- ./compiler/lua53.can:202 -["tag"] = "Index", -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "Id", -- ./compiler/lua53.can:202 -list["id"] -- ./compiler/lua53.can:202 -}, -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "String", -- ./compiler/lua53.can:202 -v[1] -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 -var = v[2] -- ./compiler/lua53.can:204 -val = { -- ./compiler/lua53.can:205 -["tag"] = "Index", -- ./compiler/lua53.can:205 -{ -- ./compiler/lua53.can:205 -["tag"] = "Id", -- ./compiler/lua53.can:205 -list["id"] -- ./compiler/lua53.can:205 -}, -- ./compiler/lua53.can:205 -v[1] -- ./compiler/lua53.can:205 -} -- ./compiler/lua53.can:205 -else -- ./compiler/lua53.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 -end -- ./compiler/lua53.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 -val = { -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["rightOp"], -- ./compiler/lua53.can:210 -var, -- ./compiler/lua53.can:210 -{ -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["leftOp"], -- ./compiler/lua53.can:210 -val, -- ./compiler/lua53.can:210 -var -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 -val = { -- ./compiler/lua53.can:212 -["tag"] = "Op", -- ./compiler/lua53.can:212 -destructured["rightOp"], -- ./compiler/lua53.can:212 -var, -- ./compiler/lua53.can:212 -val -- ./compiler/lua53.can:212 -} -- ./compiler/lua53.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 -val = { -- ./compiler/lua53.can:214 -["tag"] = "Op", -- ./compiler/lua53.can:214 -destructured["leftOp"], -- ./compiler/lua53.can:214 -val, -- ./compiler/lua53.can:214 -var -- ./compiler/lua53.can:214 -} -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -if # vars > 0 then -- ./compiler/lua53.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 -if newlineAfter then -- ./compiler/lua53.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 -else -- ./compiler/lua53.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 -end -- ./compiler/lua53.can:225 -else -- ./compiler/lua53.can:225 -return "" -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -tags = setmetatable({ -- ./compiler/lua53.can:233 -["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 -hasPush = false -- ./compiler/lua53.can:239 -end -- ./compiler/lua53.can:239 -local r = push("scope", {}) -- ./compiler/lua53.can:241 -if hasPush then -- ./compiler/lua53.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 -end -- ./compiler/lua53.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:246 -end -- ./compiler/lua53.can:246 -if t[# t] then -- ./compiler/lua53.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 -end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. pop("scope") -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Do"] = function(t) -- ./compiler/lua53.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 -end, -- ./compiler/lua53.can:261 -["Set"] = function(t) -- ./compiler/lua53.can:264 -local expr = t[# t] -- ./compiler/lua53.can:266 -local vars, values = {}, {} -- ./compiler/lua53.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 -else -- ./compiler/lua53.can:272 -table["insert"](vars, n) -- ./compiler/lua53.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 -local r = "" -- ./compiler/lua53.can:280 -if # vars > 0 then -- ./compiler/lua53.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 -end -- ./compiler/lua53.can:282 -if # destructuringVars > 0 then -- ./compiler/lua53.can:284 -local destructured = {} -- ./compiler/lua53.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 -end -- ./compiler/lua53.can:287 -return r -- ./compiler/lua53.can:289 -elseif # t == 4 then -- ./compiler/lua53.can:290 -if t[3] == "=" then -- ./compiler/lua53.can:291 -local r = "" -- ./compiler/lua53.can:292 -if # vars > 0 then -- ./compiler/lua53.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 -t[2], -- ./compiler/lua53.can:294 -vars[1], -- ./compiler/lua53.can:294 -{ -- ./compiler/lua53.can:294 -["tag"] = "Paren", -- ./compiler/lua53.can:294 -values[1] -- ./compiler/lua53.can:294 -} -- ./compiler/lua53.can:294 -}, "Op")) -- ./compiler/lua53.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 -t[2], -- ./compiler/lua53.can:296 -vars[i], -- ./compiler/lua53.can:296 -{ -- ./compiler/lua53.can:296 -["tag"] = "Paren", -- ./compiler/lua53.can:296 -values[i] -- ./compiler/lua53.can:296 -} -- ./compiler/lua53.can:296 -}, "Op")) -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -if # destructuringVars > 0 then -- ./compiler/lua53.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:302 -end -- ./compiler/lua53.can:302 -return r -- ./compiler/lua53.can:304 -else -- ./compiler/lua53.can:304 -local r = "" -- ./compiler/lua53.can:306 -if # vars > 0 then -- ./compiler/lua53.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 -t[3], -- ./compiler/lua53.can:308 -{ -- ./compiler/lua53.can:308 -["tag"] = "Paren", -- ./compiler/lua53.can:308 -values[1] -- ./compiler/lua53.can:308 -}, -- ./compiler/lua53.can:308 -vars[1] -- ./compiler/lua53.can:308 -}, "Op")) -- ./compiler/lua53.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 -t[3], -- ./compiler/lua53.can:310 -{ -- ./compiler/lua53.can:310 -["tag"] = "Paren", -- ./compiler/lua53.can:310 -values[i] -- ./compiler/lua53.can:310 -}, -- ./compiler/lua53.can:310 -vars[i] -- ./compiler/lua53.can:310 -}, "Op")) -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -if # destructuringVars > 0 then -- ./compiler/lua53.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 -end -- ./compiler/lua53.can:316 -return r -- ./compiler/lua53.can:318 -end -- ./compiler/lua53.can:318 -else -- ./compiler/lua53.can:318 -local r = "" -- ./compiler/lua53.can:321 -if # vars > 0 then -- ./compiler/lua53.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 -t[2], -- ./compiler/lua53.can:323 -vars[1], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Op", -- ./compiler/lua53.can:323 -t[4], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Paren", -- ./compiler/lua53.can:323 -values[1] -- ./compiler/lua53.can:323 -}, -- ./compiler/lua53.can:323 -vars[1] -- ./compiler/lua53.can:323 -} -- ./compiler/lua53.can:323 -}, "Op")) -- ./compiler/lua53.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 -t[2], -- ./compiler/lua53.can:325 -vars[i], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Op", -- ./compiler/lua53.can:325 -t[4], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Paren", -- ./compiler/lua53.can:325 -values[i] -- ./compiler/lua53.can:325 -}, -- ./compiler/lua53.can:325 -vars[i] -- ./compiler/lua53.can:325 -} -- ./compiler/lua53.can:325 -}, "Op")) -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -if # destructuringVars > 0 then -- ./compiler/lua53.can:328 -local destructured = { -- ./compiler/lua53.can:329 -["rightOp"] = t[2], -- ./compiler/lua53.can:329 -["leftOp"] = t[4] -- ./compiler/lua53.can:329 -} -- ./compiler/lua53.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 -end -- ./compiler/lua53.can:331 -return r -- ./compiler/lua53.can:333 -end -- ./compiler/lua53.can:333 -end, -- ./compiler/lua53.can:333 -["While"] = function(t) -- ./compiler/lua53.can:337 -local r = "" -- ./compiler/lua53.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 -if # lets > 0 then -- ./compiler/lua53.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 -if # lets > 0 then -- ./compiler/lua53.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 -end -- ./compiler/lua53.can:349 -if hasContinue then -- ./compiler/lua53.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 -end -- ./compiler/lua53.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 -if hasContinue then -- ./compiler/lua53.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 -end -- ./compiler/lua53.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 -if # lets > 0 then -- ./compiler/lua53.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 -end -- ./compiler/lua53.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 -end -- ./compiler/lua53.can:363 -return r -- ./compiler/lua53.can:365 -end, -- ./compiler/lua53.can:365 -["Repeat"] = function(t) -- ./compiler/lua53.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 -local r = "repeat" .. indent() -- ./compiler/lua53.can:370 -if hasContinue then -- ./compiler/lua53.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 -end -- ./compiler/lua53.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 -if hasContinue then -- ./compiler/lua53.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 -return r -- ./compiler/lua53.can:379 -end, -- ./compiler/lua53.can:379 -["If"] = function(t) -- ./compiler/lua53.can:382 -local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- ./compiler/lua53.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 -if # lets > 0 then -- ./compiler/lua53.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 -toClose = toClose + (1) -- ./compiler/lua53.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 -if # lets > 0 then -- ./compiler/lua53.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 -toClose = toClose + (1) -- ./compiler/lua53.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 -end -- ./compiler/lua53.can:400 -else -- ./compiler/lua53.can:400 -r = r .. ("else") -- ./compiler/lua53.can:403 -end -- ./compiler/lua53.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -if # t % 2 == 1 then -- ./compiler/lua53.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 -end -- ./compiler/lua53.can:408 -r = r .. ("end") -- ./compiler/lua53.can:410 -for i = 1, toClose do -- ./compiler/lua53.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 -end -- ./compiler/lua53.can:412 -return r -- ./compiler/lua53.can:414 -end, -- ./compiler/lua53.can:414 -["Fornum"] = function(t) -- ./compiler/lua53.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 -if # t == 5 then -- ./compiler/lua53.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 -if hasContinue then -- ./compiler/lua53.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 -if hasContinue then -- ./compiler/lua53.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 -end -- ./compiler/lua53.can:427 -return r .. unindent() .. "end" -- ./compiler/lua53.can:429 -else -- ./compiler/lua53.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 -if hasContinue then -- ./compiler/lua53.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 -end -- ./compiler/lua53.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 -if hasContinue then -- ./compiler/lua53.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 -end -- ./compiler/lua53.can:438 -return r .. unindent() .. "end" -- ./compiler/lua53.can:440 -end -- ./compiler/lua53.can:440 -end, -- ./compiler/lua53.can:440 -["Forin"] = function(t) -- ./compiler/lua53.can:444 -local destructured = {} -- ./compiler/lua53.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 -if hasContinue then -- ./compiler/lua53.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 -end -- ./compiler/lua53.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 -if hasContinue then -- ./compiler/lua53.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 -end -- ./compiler/lua53.can:453 -return r .. unindent() .. "end" -- ./compiler/lua53.can:455 -end, -- ./compiler/lua53.can:455 -["Local"] = function(t) -- ./compiler/lua53.can:458 -local destructured = {} -- ./compiler/lua53.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 -if t[2][1] then -- ./compiler/lua53.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 -end -- ./compiler/lua53.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 -end, -- ./compiler/lua53.can:464 -["Let"] = function(t) -- ./compiler/lua53.can:467 -local destructured = {} -- ./compiler/lua53.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 -local r = "local " .. nameList -- ./compiler/lua53.can:470 -if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- ./compiler/lua53.can:472 -"Nil", -- ./compiler/lua53.can:472 -"Dots", -- ./compiler/lua53.can:472 -"Boolean", -- ./compiler/lua53.can:472 -"Number", -- ./compiler/lua53.can:472 -"String" -- ./compiler/lua53.can:472 -}) then -- ./compiler/lua53.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 -else -- ./compiler/lua53.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["Localrec"] = function(t) -- ./compiler/lua53.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["Goto"] = function(t) -- ./compiler/lua53.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["Label"] = function(t) -- ./compiler/lua53.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 -end, -- ./compiler/lua53.can:490 -["Return"] = function(t) -- ./compiler/lua53.can:493 -local push = peek("push") -- ./compiler/lua53.can:494 -if push then -- ./compiler/lua53.can:495 -local r = "" -- ./compiler/lua53.can:496 -for _, val in ipairs(t) do -- ./compiler/lua53.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 -end -- ./compiler/lua53.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 -else -- ./compiler/lua53.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 -end -- ./compiler/lua53.can:502 -end, -- ./compiler/lua53.can:502 -["Push"] = function(t) -- ./compiler/lua53.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 -r = "" -- ./compiler/lua53.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 -end -- ./compiler/lua53.can:510 -if t[# t] then -- ./compiler/lua53.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 -else -- ./compiler/lua53.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -return r -- ./compiler/lua53.can:519 -end, -- ./compiler/lua53.can:519 -["Break"] = function() -- ./compiler/lua53.can:522 -return "break" -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["Continue"] = function() -- ./compiler/lua53.can:526 -return "goto " .. var("continue") -- ./compiler/lua53.can:527 -end, -- ./compiler/lua53.can:527 -["Nil"] = function() -- ./compiler/lua53.can:534 -return "nil" -- ./compiler/lua53.can:535 -end, -- ./compiler/lua53.can:535 -["Dots"] = function() -- ./compiler/lua53.can:538 -return "..." -- ./compiler/lua53.can:539 -end, -- ./compiler/lua53.can:539 -["Boolean"] = function(t) -- ./compiler/lua53.can:542 -return tostring(t[1]) -- ./compiler/lua53.can:543 -end, -- ./compiler/lua53.can:543 -["Number"] = function(t) -- ./compiler/lua53.can:546 -return tostring(t[1]) -- ./compiler/lua53.can:547 -end, -- ./compiler/lua53.can:547 -["String"] = function(t) -- ./compiler/lua53.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 -end, -- ./compiler/lua53.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 -local r = "(" -- ./compiler/lua53.can:555 -local decl = {} -- ./compiler/lua53.can:556 -if t[1][1] then -- ./compiler/lua53.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 -r = r .. (id) -- ./compiler/lua53.can:563 -else -- ./compiler/lua53.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 -end -- ./compiler/lua53.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 -r = r .. (", " .. id) -- ./compiler/lua53.can:573 -else -- ./compiler/lua53.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 -r = r .. (d .. newline()) -- ./compiler/lua53.can:581 -end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 -end -- ./compiler/lua53.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 -if hasPush then -- ./compiler/lua53.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 -else -- ./compiler/lua53.can:588 -push("push", false) -- ./compiler/lua53.can:590 -end -- ./compiler/lua53.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 -end -- ./compiler/lua53.can:594 -pop("push") -- ./compiler/lua53.can:596 -return r .. unindent() .. "end" -- ./compiler/lua53.can:597 -end, -- ./compiler/lua53.can:597 -["Function"] = function(t) -- ./compiler/lua53.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 -end, -- ./compiler/lua53.can:600 -["Pair"] = function(t) -- ./compiler/lua53.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 -end, -- ./compiler/lua53.can:604 -["Table"] = function(t) -- ./compiler/lua53.can:606 -if # t == 0 then -- ./compiler/lua53.can:607 -return "{}" -- ./compiler/lua53.can:608 -elseif # t == 1 then -- ./compiler/lua53.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 -else -- ./compiler/lua53.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 -end -- ./compiler/lua53.can:612 -end, -- ./compiler/lua53.can:612 -["TableCompr"] = function(t) -- ./compiler/lua53.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 -end, -- ./compiler/lua53.can:617 -["Op"] = function(t) -- ./compiler/lua53.can:620 -local r -- ./compiler/lua53.can:621 -if # t == 2 then -- ./compiler/lua53.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 -else -- ./compiler/lua53.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 -end -- ./compiler/lua53.can:626 -else -- ./compiler/lua53.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 -else -- ./compiler/lua53.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -return r -- ./compiler/lua53.can:635 -end, -- ./compiler/lua53.can:635 -["Paren"] = function(t) -- ./compiler/lua53.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 -end, -- ./compiler/lua53.can:639 -["MethodStub"] = function(t) -- ./compiler/lua53.can:642 -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:648 -end, -- ./compiler/lua53.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 -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:658 -end, -- ./compiler/lua53.can:658 -["LetExpr"] = function(t) -- ./compiler/lua53.can:665 -return lua(t[1][1]) -- ./compiler/lua53.can:666 -end, -- ./compiler/lua53.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 -local r = "(function()" .. indent() -- ./compiler/lua53.can:672 -if hasPush then -- ./compiler/lua53.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 -else -- ./compiler/lua53.can:674 -push("push", false) -- ./compiler/lua53.can:676 -end -- ./compiler/lua53.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 -if hasPush then -- ./compiler/lua53.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 -end -- ./compiler/lua53.can:680 -pop("push") -- ./compiler/lua53.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 -return r -- ./compiler/lua53.can:684 -end, -- ./compiler/lua53.can:684 -["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 -end -- ./compiler/lua53.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 -end, -- ./compiler/lua53.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 -end, -- ./compiler/lua53.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 -end, -- ./compiler/lua53.can:699 -["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- ./compiler/lua53.can:703 -local block = t[i] -- ./compiler/lua53.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 -end, -- ./compiler/lua53.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 -end, -- ./compiler/lua53.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 -end, -- ./compiler/lua53.can:717 -["Call"] = function(t) -- ./compiler/lua53.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 -else -- ./compiler/lua53.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 -end -- ./compiler/lua53.can:730 -else -- ./compiler/lua53.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 -end -- ./compiler/lua53.can:733 -end, -- ./compiler/lua53.can:733 -["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 -else -- ./compiler/lua53.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 -end -- ./compiler/lua53.can:741 -end, -- ./compiler/lua53.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 -if start == nil then start = 1 end -- ./compiler/lua53.can:746 -local r -- ./compiler/lua53.can:747 -if t[start] then -- ./compiler/lua53.can:748 -r = lua(t[start]) -- ./compiler/lua53.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 -end -- ./compiler/lua53.can:751 -else -- ./compiler/lua53.can:751 -r = "" -- ./compiler/lua53.can:754 -end -- ./compiler/lua53.can:754 -return r -- ./compiler/lua53.can:756 -end, -- ./compiler/lua53.can:756 -["Id"] = function(t) -- ./compiler/lua53.can:759 -return t[1] -- ./compiler/lua53.can:760 -end, -- ./compiler/lua53.can:760 -["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- ./compiler/lua53.can:764 -return t["id"] -- ./compiler/lua53.can:765 -else -- ./compiler/lua53.can:765 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 -local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 -for j = 1, # t, 1 do -- ./compiler/lua53.can:769 -table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 -end -- ./compiler/lua53.can:770 -table["insert"](d, vars) -- ./compiler/lua53.can:772 -t["id"] = vars["id"] -- ./compiler/lua53.can:773 -return vars["id"] -- ./compiler/lua53.can:774 -end -- ./compiler/lua53.can:774 -end, -- ./compiler/lua53.can:774 -["Index"] = function(t) -- ./compiler/lua53.can:778 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 -else -- ./compiler/lua53.can:780 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 -end -- ./compiler/lua53.can:782 -end, -- ./compiler/lua53.can:782 -["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 -local l = {} -- ./compiler/lua53.can:788 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 -table["insert"](l, 1, t) -- ./compiler/lua53.can:790 -t = t[1] -- ./compiler/lua53.can:791 -end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 -for _, e in ipairs(l) do -- ./compiler/lua53.can:794 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 -if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 -else -- ./compiler/lua53.can:797 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 -return r -- ./compiler/lua53.can:803 -else -- ./compiler/lua53.can:803 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 -end -- ./compiler/lua53.can:805 -end, -- ./compiler/lua53.can:805 -["_opid"] = { -- ./compiler/lua53.can:810 -["add"] = "+", -- ./compiler/lua53.can:811 -["sub"] = "-", -- ./compiler/lua53.can:811 -["mul"] = "*", -- ./compiler/lua53.can:811 -["div"] = "/", -- ./compiler/lua53.can:811 -["idiv"] = "//", -- ./compiler/lua53.can:812 -["mod"] = "%", -- ./compiler/lua53.can:812 -["pow"] = "^", -- ./compiler/lua53.can:812 -["concat"] = "..", -- ./compiler/lua53.can:812 -["band"] = "&", -- ./compiler/lua53.can:813 -["bor"] = "|", -- ./compiler/lua53.can:813 -["bxor"] = "~", -- ./compiler/lua53.can:813 -["shl"] = "<<", -- ./compiler/lua53.can:813 -["shr"] = ">>", -- ./compiler/lua53.can:813 -["eq"] = "==", -- ./compiler/lua53.can:814 -["ne"] = "~=", -- ./compiler/lua53.can:814 -["lt"] = "<", -- ./compiler/lua53.can:814 -["gt"] = ">", -- ./compiler/lua53.can:814 -["le"] = "<=", -- ./compiler/lua53.can:814 -["ge"] = ">=", -- ./compiler/lua53.can:814 -["and"] = "and", -- ./compiler/lua53.can:815 -["or"] = "or", -- ./compiler/lua53.can:815 -["unm"] = "-", -- ./compiler/lua53.can:815 -["len"] = "#", -- ./compiler/lua53.can:815 -["bnot"] = "~", -- ./compiler/lua53.can:815 -["not"] = "not" -- ./compiler/lua53.can:815 -} -- ./compiler/lua53.can:815 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 -end }) -- ./compiler/lua53.can:819 -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 " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/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:825 -return requireStr .. code -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -local lua53 = _() or lua53 -- ./compiler/lua53.can:831 +") do -- ./compiler/lua54.can:23 +lastLine = lastLine + (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +prevLinePos = lastInputPos -- ./compiler/lua54.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 +end -- ./compiler/lua54.can:30 +return r -- ./compiler/lua54.can:32 +end -- ./compiler/lua54.can:32 +local function indent() -- ./compiler/lua54.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 +return newline() -- ./compiler/lua54.can:37 +end -- ./compiler/lua54.can:37 +local function unindent() -- ./compiler/lua54.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 +return newline() -- ./compiler/lua54.can:42 +end -- ./compiler/lua54.can:42 +local states = { -- ./compiler/lua54.can:47 +["push"] = {}, -- ./compiler/lua54.can:48 +["destructuring"] = {}, -- ./compiler/lua54.can:49 +["scope"] = {} -- ./compiler/lua54.can:50 +} -- ./compiler/lua54.can:50 +local function push(name, state) -- ./compiler/lua54.can:53 +table["insert"](states[name], state) -- ./compiler/lua54.can:54 +return "" -- ./compiler/lua54.can:55 +end -- ./compiler/lua54.can:55 +local function pop(name) -- ./compiler/lua54.can:58 +table["remove"](states[name]) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function set(name, state) -- ./compiler/lua54.can:63 +states[name][# states[name]] = state -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function peek(name) -- ./compiler/lua54.can:68 +return states[name][# states[name]] -- ./compiler/lua54.can:69 +end -- ./compiler/lua54.can:69 +local function var(name) -- ./compiler/lua54.can:74 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 +end -- ./compiler/lua54.can:75 +local function tmp() -- ./compiler/lua54.can:79 +local scope = peek("scope") -- ./compiler/lua54.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 +table["insert"](scope, var) -- ./compiler/lua54.can:82 +return var -- ./compiler/lua54.can:83 +end -- ./compiler/lua54.can:83 +local required = {} -- ./compiler/lua54.can:87 +local requireStr = "" -- ./compiler/lua54.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 +if not required[req] then -- ./compiler/lua54.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 +required[req] = true -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +local loop = { -- ./compiler/lua54.can:99 +"While", -- ./compiler/lua54.can:99 +"Repeat", -- ./compiler/lua54.can:99 +"Fornum", -- ./compiler/lua54.can:99 +"Forin", -- ./compiler/lua54.can:99 +"WhileExpr", -- ./compiler/lua54.can:99 +"RepeatExpr", -- ./compiler/lua54.can:99 +"FornumExpr", -- ./compiler/lua54.can:99 +"ForinExpr" -- ./compiler/lua54.can:99 +} -- ./compiler/lua54.can:99 +local func = { -- ./compiler/lua54.can:100 +"Function", -- ./compiler/lua54.can:100 +"TableCompr", -- ./compiler/lua54.can:100 +"DoExpr", -- ./compiler/lua54.can:100 +"WhileExpr", -- ./compiler/lua54.can:100 +"RepeatExpr", -- ./compiler/lua54.can:100 +"IfExpr", -- ./compiler/lua54.can:100 +"FornumExpr", -- ./compiler/lua54.can:100 +"ForinExpr" -- ./compiler/lua54.can:100 +} -- ./compiler/lua54.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 +local tagsCheck = {} -- ./compiler/lua54.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 +tagsCheck[tag] = true -- ./compiler/lua54.can:107 +end -- ./compiler/lua54.can:107 +local nofollowCheck = {} -- ./compiler/lua54.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 +nofollowCheck[tag] = true -- ./compiler/lua54.can:111 +end -- ./compiler/lua54.can:111 +for _, node in ipairs(list) do -- ./compiler/lua54.can:113 +if type(node) == "table" then -- ./compiler/lua54.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 +return node -- ./compiler/lua54.can:116 +end -- ./compiler/lua54.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 +if r then -- ./compiler/lua54.can:120 +return r -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +return nil -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 +local tagsCheck = {} -- ./compiler/lua54.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 +tagsCheck[tag] = true -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local nofollowCheck = {} -- ./compiler/lua54.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 +nofollowCheck[tag] = true -- ./compiler/lua54.can:136 +end -- ./compiler/lua54.can:136 +local found = {} -- ./compiler/lua54.can:138 +for _, node in ipairs(list) do -- ./compiler/lua54.can:139 +if type(node) == "table" then -- ./compiler/lua54.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 +table["insert"](found, n) -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 +table["insert"](found, node) -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +return found -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +local function all(list, tags) -- ./compiler/lua54.can:155 +for _, node in ipairs(list) do -- ./compiler/lua54.can:156 +local ok = false -- ./compiler/lua54.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 +if node["tag"] == tag then -- ./compiler/lua54.can:159 +ok = true -- ./compiler/lua54.can:160 +break -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +if not ok then -- ./compiler/lua54.can:164 +return false -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +return true -- ./compiler/lua54.can:168 +end -- ./compiler/lua54.can:168 +local tags -- ./compiler/lua54.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 +end -- ./compiler/lua54.can:178 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 +end -- ./compiler/lua54.can:183 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local CONTINUE_START = function() -- ./compiler/lua54.can:188 +return "do" .. indent() -- ./compiler/lua54.can:189 +end -- ./compiler/lua54.can:189 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +end -- ./compiler/lua54.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 +local vars = {} -- ./compiler/lua54.can:195 +local values = {} -- ./compiler/lua54.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 +for _, v in ipairs(list) do -- ./compiler/lua54.can:198 +local var, val -- ./compiler/lua54.can:199 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 +var = v -- ./compiler/lua54.can:201 +val = { -- ./compiler/lua54.can:202 +["tag"] = "Index", -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "Id", -- ./compiler/lua54.can:202 +list["id"] -- ./compiler/lua54.can:202 +}, -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "String", -- ./compiler/lua54.can:202 +v[1] -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 +var = v[2] -- ./compiler/lua54.can:204 +val = { -- ./compiler/lua54.can:205 +["tag"] = "Index", -- ./compiler/lua54.can:205 +{ -- ./compiler/lua54.can:205 +["tag"] = "Id", -- ./compiler/lua54.can:205 +list["id"] -- ./compiler/lua54.can:205 +}, -- ./compiler/lua54.can:205 +v[1] -- ./compiler/lua54.can:205 +} -- ./compiler/lua54.can:205 +else -- ./compiler/lua54.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 +end -- ./compiler/lua54.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["rightOp"], -- ./compiler/lua54.can:210 +var, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["leftOp"], -- ./compiler/lua54.can:210 +val, -- ./compiler/lua54.can:210 +var -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 +val = { -- ./compiler/lua54.can:212 +["tag"] = "Op", -- ./compiler/lua54.can:212 +destructured["rightOp"], -- ./compiler/lua54.can:212 +var, -- ./compiler/lua54.can:212 +val -- ./compiler/lua54.can:212 +} -- ./compiler/lua54.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 +val = { -- ./compiler/lua54.can:214 +["tag"] = "Op", -- ./compiler/lua54.can:214 +destructured["leftOp"], -- ./compiler/lua54.can:214 +val, -- ./compiler/lua54.can:214 +var -- ./compiler/lua54.can:214 +} -- ./compiler/lua54.can:214 +end -- ./compiler/lua54.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +if # vars > 0 then -- ./compiler/lua54.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 +if newlineAfter then -- ./compiler/lua54.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 +else -- ./compiler/lua54.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +else -- ./compiler/lua54.can:225 +return "" -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +tags = setmetatable({ -- ./compiler/lua54.can:233 +["Block"] = function(t) -- ./compiler/lua54.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 +hasPush = false -- ./compiler/lua54.can:239 +end -- ./compiler/lua54.can:239 +local r = push("scope", {}) -- ./compiler/lua54.can:241 +if hasPush then -- ./compiler/lua54.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 +end -- ./compiler/lua54.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 +end -- ./compiler/lua54.can:246 +if t[# t] then -- ./compiler/lua54.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +end -- ./compiler/lua54.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +end -- ./compiler/lua54.can:252 +return r .. pop("scope") -- ./compiler/lua54.can:254 +end, -- ./compiler/lua54.can:254 +["Do"] = function(t) -- ./compiler/lua54.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 +end, -- ./compiler/lua54.can:261 +["Set"] = function(t) -- ./compiler/lua54.can:264 +local expr = t[# t] -- ./compiler/lua54.can:266 +local vars, values = {}, {} -- ./compiler/lua54.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 +else -- ./compiler/lua54.can:272 +table["insert"](vars, n) -- ./compiler/lua54.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 +local r = "" -- ./compiler/lua54.can:280 +if # vars > 0 then -- ./compiler/lua54.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 +end -- ./compiler/lua54.can:282 +if # destructuringVars > 0 then -- ./compiler/lua54.can:284 +local destructured = {} -- ./compiler/lua54.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 +end -- ./compiler/lua54.can:287 +return r -- ./compiler/lua54.can:289 +elseif # t == 4 then -- ./compiler/lua54.can:290 +if t[3] == "=" then -- ./compiler/lua54.can:291 +local r = "" -- ./compiler/lua54.can:292 +if # vars > 0 then -- ./compiler/lua54.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 +t[2], -- ./compiler/lua54.can:294 +vars[1], -- ./compiler/lua54.can:294 +{ -- ./compiler/lua54.can:294 +["tag"] = "Paren", -- ./compiler/lua54.can:294 +values[1] -- ./compiler/lua54.can:294 +} -- ./compiler/lua54.can:294 +}, "Op")) -- ./compiler/lua54.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 +t[2], -- ./compiler/lua54.can:296 +vars[i], -- ./compiler/lua54.can:296 +{ -- ./compiler/lua54.can:296 +["tag"] = "Paren", -- ./compiler/lua54.can:296 +values[i] -- ./compiler/lua54.can:296 +} -- ./compiler/lua54.can:296 +}, "Op")) -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +if # destructuringVars > 0 then -- ./compiler/lua54.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +end -- ./compiler/lua54.can:302 +return r -- ./compiler/lua54.can:304 +else -- ./compiler/lua54.can:304 +local r = "" -- ./compiler/lua54.can:306 +if # vars > 0 then -- ./compiler/lua54.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 +t[3], -- ./compiler/lua54.can:308 +{ -- ./compiler/lua54.can:308 +["tag"] = "Paren", -- ./compiler/lua54.can:308 +values[1] -- ./compiler/lua54.can:308 +}, -- ./compiler/lua54.can:308 +vars[1] -- ./compiler/lua54.can:308 +}, "Op")) -- ./compiler/lua54.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 +t[3], -- ./compiler/lua54.can:310 +{ -- ./compiler/lua54.can:310 +["tag"] = "Paren", -- ./compiler/lua54.can:310 +values[i] -- ./compiler/lua54.can:310 +}, -- ./compiler/lua54.can:310 +vars[i] -- ./compiler/lua54.can:310 +}, "Op")) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +if # destructuringVars > 0 then -- ./compiler/lua54.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:316 +return r -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +else -- ./compiler/lua54.can:318 +local r = "" -- ./compiler/lua54.can:321 +if # vars > 0 then -- ./compiler/lua54.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 +t[2], -- ./compiler/lua54.can:323 +vars[1], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Op", -- ./compiler/lua54.can:323 +t[4], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Paren", -- ./compiler/lua54.can:323 +values[1] -- ./compiler/lua54.can:323 +}, -- ./compiler/lua54.can:323 +vars[1] -- ./compiler/lua54.can:323 +} -- ./compiler/lua54.can:323 +}, "Op")) -- ./compiler/lua54.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 +t[2], -- ./compiler/lua54.can:325 +vars[i], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Op", -- ./compiler/lua54.can:325 +t[4], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Paren", -- ./compiler/lua54.can:325 +values[i] -- ./compiler/lua54.can:325 +}, -- ./compiler/lua54.can:325 +vars[i] -- ./compiler/lua54.can:325 +} -- ./compiler/lua54.can:325 +}, "Op")) -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +if # destructuringVars > 0 then -- ./compiler/lua54.can:328 +local destructured = { -- ./compiler/lua54.can:329 +["rightOp"] = t[2], -- ./compiler/lua54.can:329 +["leftOp"] = t[4] -- ./compiler/lua54.can:329 +} -- ./compiler/lua54.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +end -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end, -- ./compiler/lua54.can:333 +["While"] = function(t) -- ./compiler/lua54.can:337 +local r = "" -- ./compiler/lua54.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 +if # lets > 0 then -- ./compiler/lua54.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 +if # lets > 0 then -- ./compiler/lua54.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 +end -- ./compiler/lua54.can:349 +if hasContinue then -- ./compiler/lua54.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 +if hasContinue then -- ./compiler/lua54.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 +end -- ./compiler/lua54.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 +if # lets > 0 then -- ./compiler/lua54.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 +end -- ./compiler/lua54.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 +end -- ./compiler/lua54.can:363 +return r -- ./compiler/lua54.can:365 +end, -- ./compiler/lua54.can:365 +["Repeat"] = function(t) -- ./compiler/lua54.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 +local r = "repeat" .. indent() -- ./compiler/lua54.can:370 +if hasContinue then -- ./compiler/lua54.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 +end -- ./compiler/lua54.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 +if hasContinue then -- ./compiler/lua54.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 +end -- ./compiler/lua54.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 +return r -- ./compiler/lua54.can:379 +end, -- ./compiler/lua54.can:379 +["If"] = function(t) -- ./compiler/lua54.can:382 +local r = "" -- ./compiler/lua54.can:383 +local toClose = 0 -- ./compiler/lua54.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 +if # lets > 0 then -- ./compiler/lua54.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 +toClose = toClose + (1) -- ./compiler/lua54.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 +if # lets > 0 then -- ./compiler/lua54.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 +toClose = toClose + (1) -- ./compiler/lua54.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 +end -- ./compiler/lua54.can:400 +else -- ./compiler/lua54.can:400 +r = r .. ("else") -- ./compiler/lua54.can:403 +end -- ./compiler/lua54.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 +end -- ./compiler/lua54.can:405 +if # t % 2 == 1 then -- ./compiler/lua54.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +r = r .. ("end") -- ./compiler/lua54.can:410 +for i = 1, toClose do -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 +end -- ./compiler/lua54.can:412 +return r -- ./compiler/lua54.can:414 +end, -- ./compiler/lua54.can:414 +["Fornum"] = function(t) -- ./compiler/lua54.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 +if # t == 5 then -- ./compiler/lua54.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 +if hasContinue then -- ./compiler/lua54.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 +end -- ./compiler/lua54.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 +if hasContinue then -- ./compiler/lua54.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 +end -- ./compiler/lua54.can:427 +return r .. unindent() .. "end" -- ./compiler/lua54.can:429 +else -- ./compiler/lua54.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 +if hasContinue then -- ./compiler/lua54.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 +end -- ./compiler/lua54.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 +if hasContinue then -- ./compiler/lua54.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 +end -- ./compiler/lua54.can:438 +return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:440 +end, -- ./compiler/lua54.can:440 +["Forin"] = function(t) -- ./compiler/lua54.can:444 +local destructured = {} -- ./compiler/lua54.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 +if hasContinue then -- ./compiler/lua54.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 +end -- ./compiler/lua54.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 +if hasContinue then -- ./compiler/lua54.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 +end -- ./compiler/lua54.can:453 +return r .. unindent() .. "end" -- ./compiler/lua54.can:455 +end, -- ./compiler/lua54.can:455 +["Local"] = function(t) -- ./compiler/lua54.can:458 +local destructured = {} -- ./compiler/lua54.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 +if t[2][1] then -- ./compiler/lua54.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 +end -- ./compiler/lua54.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 +end, -- ./compiler/lua54.can:464 +["Let"] = function(t) -- ./compiler/lua54.can:467 +local destructured = {} -- ./compiler/lua54.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 +local r = "local " .. nameList -- ./compiler/lua54.can:470 +if t[2][1] then -- ./compiler/lua54.can:471 +if all(t[2], { -- ./compiler/lua54.can:472 +"Nil", -- ./compiler/lua54.can:472 +"Dots", -- ./compiler/lua54.can:472 +"Boolean", -- ./compiler/lua54.can:472 +"Number", -- ./compiler/lua54.can:472 +"String" -- ./compiler/lua54.can:472 +}) then -- ./compiler/lua54.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 +else -- ./compiler/lua54.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 +end, -- ./compiler/lua54.can:478 +["Localrec"] = function(t) -- ./compiler/lua54.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 +end, -- ./compiler/lua54.can:482 +["Goto"] = function(t) -- ./compiler/lua54.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Label"] = function(t) -- ./compiler/lua54.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Return"] = function(t) -- ./compiler/lua54.can:493 +local push = peek("push") -- ./compiler/lua54.can:494 +if push then -- ./compiler/lua54.can:495 +local r = "" -- ./compiler/lua54.can:496 +for _, val in ipairs(t) do -- ./compiler/lua54.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 +end -- ./compiler/lua54.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 +else -- ./compiler/lua54.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 +end -- ./compiler/lua54.can:502 +end, -- ./compiler/lua54.can:502 +["Push"] = function(t) -- ./compiler/lua54.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 +r = "" -- ./compiler/lua54.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +if t[# t] then -- ./compiler/lua54.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 +else -- ./compiler/lua54.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +return r -- ./compiler/lua54.can:519 +end, -- ./compiler/lua54.can:519 +["Break"] = function() -- ./compiler/lua54.can:522 +return "break" -- ./compiler/lua54.can:523 +end, -- ./compiler/lua54.can:523 +["Continue"] = function() -- ./compiler/lua54.can:526 +return "goto " .. var("continue") -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Nil"] = function() -- ./compiler/lua54.can:534 +return "nil" -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Dots"] = function() -- ./compiler/lua54.can:538 +return "..." -- ./compiler/lua54.can:539 +end, -- ./compiler/lua54.can:539 +["Boolean"] = function(t) -- ./compiler/lua54.can:542 +return tostring(t[1]) -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Number"] = function(t) -- ./compiler/lua54.can:546 +return tostring(t[1]) -- ./compiler/lua54.can:547 +end, -- ./compiler/lua54.can:547 +["String"] = function(t) -- ./compiler/lua54.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 +end, -- ./compiler/lua54.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 +local r = "(" -- ./compiler/lua54.can:555 +local decl = {} -- ./compiler/lua54.can:556 +if t[1][1] then -- ./compiler/lua54.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 +r = r .. (id) -- ./compiler/lua54.can:563 +else -- ./compiler/lua54.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 +end -- ./compiler/lua54.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 +r = r .. (", " .. id) -- ./compiler/lua54.can:573 +else -- ./compiler/lua54.can:573 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 +r = r .. (d .. newline()) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 +end -- ./compiler/lua54.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 +if hasPush then -- ./compiler/lua54.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 +else -- ./compiler/lua54.can:588 +push("push", false) -- ./compiler/lua54.can:590 +end -- ./compiler/lua54.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 +end -- ./compiler/lua54.can:594 +pop("push") -- ./compiler/lua54.can:596 +return r .. unindent() .. "end" -- ./compiler/lua54.can:597 +end, -- ./compiler/lua54.can:597 +["Function"] = function(t) -- ./compiler/lua54.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 +end, -- ./compiler/lua54.can:600 +["Pair"] = function(t) -- ./compiler/lua54.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 +end, -- ./compiler/lua54.can:604 +["Table"] = function(t) -- ./compiler/lua54.can:606 +if # t == 0 then -- ./compiler/lua54.can:607 +return "{}" -- ./compiler/lua54.can:608 +elseif # t == 1 then -- ./compiler/lua54.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 +else -- ./compiler/lua54.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 +end -- ./compiler/lua54.can:612 +end, -- ./compiler/lua54.can:612 +["TableCompr"] = function(t) -- ./compiler/lua54.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 +end, -- ./compiler/lua54.can:617 +["Op"] = function(t) -- ./compiler/lua54.can:620 +local r -- ./compiler/lua54.can:621 +if # t == 2 then -- ./compiler/lua54.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +else -- ./compiler/lua54.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +end -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 +else -- ./compiler/lua54.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +return r -- ./compiler/lua54.can:635 +end, -- ./compiler/lua54.can:635 +["Paren"] = function(t) -- ./compiler/lua54.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 +end, -- ./compiler/lua54.can:639 +["MethodStub"] = function(t) -- ./compiler/lua54.can:642 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 +end, -- ./compiler/lua54.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 +end, -- ./compiler/lua54.can:658 +["LetExpr"] = function(t) -- ./compiler/lua54.can:665 +return lua(t[1][1]) -- ./compiler/lua54.can:666 +end, -- ./compiler/lua54.can:666 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 +local r = "(function()" .. indent() -- ./compiler/lua54.can:672 +if hasPush then -- ./compiler/lua54.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 +else -- ./compiler/lua54.can:674 +push("push", false) -- ./compiler/lua54.can:676 +end -- ./compiler/lua54.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 +if hasPush then -- ./compiler/lua54.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 +end -- ./compiler/lua54.can:680 +pop("push") -- ./compiler/lua54.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 +return r -- ./compiler/lua54.can:684 +end, -- ./compiler/lua54.can:684 +["DoExpr"] = function(t) -- ./compiler/lua54.can:687 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 +end -- ./compiler/lua54.can:689 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 +end, -- ./compiler/lua54.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 +end, -- ./compiler/lua54.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 +end, -- ./compiler/lua54.can:699 +["IfExpr"] = function(t) -- ./compiler/lua54.can:702 +for i = 2, # t do -- ./compiler/lua54.can:703 +local block = t[i] -- ./compiler/lua54.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +end, -- ./compiler/lua54.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 +end, -- ./compiler/lua54.can:717 +["Call"] = function(t) -- ./compiler/lua54.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 +else -- ./compiler/lua54.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 +end -- ./compiler/lua54.can:730 +else -- ./compiler/lua54.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 +end -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["SafeCall"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 +else -- ./compiler/lua54.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 +end -- ./compiler/lua54.can:741 +end, -- ./compiler/lua54.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 +if start == nil then start = 1 end -- ./compiler/lua54.can:746 +local r -- ./compiler/lua54.can:747 +if t[start] then -- ./compiler/lua54.can:748 +r = lua(t[start]) -- ./compiler/lua54.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 +end -- ./compiler/lua54.can:751 +else -- ./compiler/lua54.can:751 +r = "" -- ./compiler/lua54.can:754 +end -- ./compiler/lua54.can:754 +return r -- ./compiler/lua54.can:756 +end, -- ./compiler/lua54.can:756 +["Id"] = function(t) -- ./compiler/lua54.can:759 +return t[1] -- ./compiler/lua54.can:760 +end, -- ./compiler/lua54.can:760 +["AttributeId"] = function(t) -- ./compiler/lua54.can:763 +if t[2] then -- ./compiler/lua54.can:764 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 +else -- ./compiler/lua54.can:765 +return t[1] -- ./compiler/lua54.can:767 +end -- ./compiler/lua54.can:767 +end, -- ./compiler/lua54.can:767 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 +if t["id"] then -- ./compiler/lua54.can:772 +return t["id"] -- ./compiler/lua54.can:773 +else -- ./compiler/lua54.can:773 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 +for j = 1, # t, 1 do -- ./compiler/lua54.can:777 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 +end -- ./compiler/lua54.can:778 +table["insert"](d, vars) -- ./compiler/lua54.can:780 +t["id"] = vars["id"] -- ./compiler/lua54.can:781 +return vars["id"] -- ./compiler/lua54.can:782 +end -- ./compiler/lua54.can:782 +end, -- ./compiler/lua54.can:782 +["Index"] = function(t) -- ./compiler/lua54.can:786 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 +else -- ./compiler/lua54.can:788 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +end -- ./compiler/lua54.can:790 +end, -- ./compiler/lua54.can:790 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 +local l = {} -- ./compiler/lua54.can:796 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 +table["insert"](l, 1, t) -- ./compiler/lua54.can:798 +t = t[1] -- ./compiler/lua54.can:799 +end -- ./compiler/lua54.can:799 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 +for _, e in ipairs(l) do -- ./compiler/lua54.can:802 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 +else -- ./compiler/lua54.can:805 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 +return r -- ./compiler/lua54.can:811 +else -- ./compiler/lua54.can:811 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 +end -- ./compiler/lua54.can:813 +end, -- ./compiler/lua54.can:813 +["_opid"] = { -- ./compiler/lua54.can:818 +["add"] = "+", -- ./compiler/lua54.can:819 +["sub"] = "-", -- ./compiler/lua54.can:819 +["mul"] = "*", -- ./compiler/lua54.can:819 +["div"] = "/", -- ./compiler/lua54.can:819 +["idiv"] = "//", -- ./compiler/lua54.can:820 +["mod"] = "%", -- ./compiler/lua54.can:820 +["pow"] = "^", -- ./compiler/lua54.can:820 +["concat"] = "..", -- ./compiler/lua54.can:820 +["band"] = "&", -- ./compiler/lua54.can:821 +["bor"] = "|", -- ./compiler/lua54.can:821 +["bxor"] = "~", -- ./compiler/lua54.can:821 +["shl"] = "<<", -- ./compiler/lua54.can:821 +["shr"] = ">>", -- ./compiler/lua54.can:821 +["eq"] = "==", -- ./compiler/lua54.can:822 +["ne"] = "~=", -- ./compiler/lua54.can:822 +["lt"] = "<", -- ./compiler/lua54.can:822 +["gt"] = ">", -- ./compiler/lua54.can:822 +["le"] = "<=", -- ./compiler/lua54.can:822 +["ge"] = ">=", -- ./compiler/lua54.can:822 +["and"] = "and", -- ./compiler/lua54.can:823 +["or"] = "or", -- ./compiler/lua54.can:823 +["unm"] = "-", -- ./compiler/lua54.can:823 +["len"] = "#", -- ./compiler/lua54.can:823 +["bnot"] = "~", -- ./compiler/lua54.can:823 +["not"] = "not" -- ./compiler/lua54.can:823 +} -- ./compiler/lua54.can:823 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 +end }) -- ./compiler/lua54.can:827 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 +return requireStr .. code -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +return lua54 -- ./compiler/lua53.can:10 +end -- ./compiler/lua53.can:10 +local lua53 = _() or lua53 -- ./compiler/lua53.can:14 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:15 +local function _() -- ./compiler/lua53.can:18 +local function _() -- ./compiler/lua53.can:20 +local function _() -- ./compiler/lua53.can:22 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +return function(code, ast, options) -- ./compiler/lua54.can:3 +local lastInputPos = 1 -- ./compiler/lua54.can:5 +local prevLinePos = 1 -- ./compiler/lua54.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 +local lastLine = 1 -- ./compiler/lua54.can:8 +local indentLevel = 0 -- ./compiler/lua54.can:11 +local function newline() -- ./compiler/lua54.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 +if options["mapLines"] then -- ./compiler/lua54.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local source, line = sub:sub(1, sub:find("\ +")):match(".*%-%- (.-)%:(%d+)\ +") -- ./compiler/lua54.can:17 +if source and line then -- ./compiler/lua54.can:19 +lastSource = source -- ./compiler/lua54.can:20 +lastLine = tonumber(line) -- ./compiler/lua54.can:21 +else -- ./compiler/lua54.can:21 +for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ +") do -- ./compiler/lua54.can:23 +lastLine = lastLine + (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +prevLinePos = lastInputPos -- ./compiler/lua54.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 +end -- ./compiler/lua54.can:30 +return r -- ./compiler/lua54.can:32 +end -- ./compiler/lua54.can:32 +local function indent() -- ./compiler/lua54.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 +return newline() -- ./compiler/lua54.can:37 +end -- ./compiler/lua54.can:37 +local function unindent() -- ./compiler/lua54.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 +return newline() -- ./compiler/lua54.can:42 +end -- ./compiler/lua54.can:42 +local states = { -- ./compiler/lua54.can:47 +["push"] = {}, -- ./compiler/lua54.can:48 +["destructuring"] = {}, -- ./compiler/lua54.can:49 +["scope"] = {} -- ./compiler/lua54.can:50 +} -- ./compiler/lua54.can:50 +local function push(name, state) -- ./compiler/lua54.can:53 +table["insert"](states[name], state) -- ./compiler/lua54.can:54 +return "" -- ./compiler/lua54.can:55 +end -- ./compiler/lua54.can:55 +local function pop(name) -- ./compiler/lua54.can:58 +table["remove"](states[name]) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function set(name, state) -- ./compiler/lua54.can:63 +states[name][# states[name]] = state -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function peek(name) -- ./compiler/lua54.can:68 +return states[name][# states[name]] -- ./compiler/lua54.can:69 +end -- ./compiler/lua54.can:69 +local function var(name) -- ./compiler/lua54.can:74 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 +end -- ./compiler/lua54.can:75 +local function tmp() -- ./compiler/lua54.can:79 +local scope = peek("scope") -- ./compiler/lua54.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 +table["insert"](scope, var) -- ./compiler/lua54.can:82 +return var -- ./compiler/lua54.can:83 +end -- ./compiler/lua54.can:83 +local required = {} -- ./compiler/lua54.can:87 +local requireStr = "" -- ./compiler/lua54.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 +if not required[req] then -- ./compiler/lua54.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 +required[req] = true -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +local loop = { -- ./compiler/lua54.can:99 +"While", -- ./compiler/lua54.can:99 +"Repeat", -- ./compiler/lua54.can:99 +"Fornum", -- ./compiler/lua54.can:99 +"Forin", -- ./compiler/lua54.can:99 +"WhileExpr", -- ./compiler/lua54.can:99 +"RepeatExpr", -- ./compiler/lua54.can:99 +"FornumExpr", -- ./compiler/lua54.can:99 +"ForinExpr" -- ./compiler/lua54.can:99 +} -- ./compiler/lua54.can:99 +local func = { -- ./compiler/lua54.can:100 +"Function", -- ./compiler/lua54.can:100 +"TableCompr", -- ./compiler/lua54.can:100 +"DoExpr", -- ./compiler/lua54.can:100 +"WhileExpr", -- ./compiler/lua54.can:100 +"RepeatExpr", -- ./compiler/lua54.can:100 +"IfExpr", -- ./compiler/lua54.can:100 +"FornumExpr", -- ./compiler/lua54.can:100 +"ForinExpr" -- ./compiler/lua54.can:100 +} -- ./compiler/lua54.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 +local tagsCheck = {} -- ./compiler/lua54.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 +tagsCheck[tag] = true -- ./compiler/lua54.can:107 +end -- ./compiler/lua54.can:107 +local nofollowCheck = {} -- ./compiler/lua54.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 +nofollowCheck[tag] = true -- ./compiler/lua54.can:111 +end -- ./compiler/lua54.can:111 +for _, node in ipairs(list) do -- ./compiler/lua54.can:113 +if type(node) == "table" then -- ./compiler/lua54.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 +return node -- ./compiler/lua54.can:116 +end -- ./compiler/lua54.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 +if r then -- ./compiler/lua54.can:120 +return r -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +return nil -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 +local tagsCheck = {} -- ./compiler/lua54.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 +tagsCheck[tag] = true -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local nofollowCheck = {} -- ./compiler/lua54.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 +nofollowCheck[tag] = true -- ./compiler/lua54.can:136 +end -- ./compiler/lua54.can:136 +local found = {} -- ./compiler/lua54.can:138 +for _, node in ipairs(list) do -- ./compiler/lua54.can:139 +if type(node) == "table" then -- ./compiler/lua54.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 +table["insert"](found, n) -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 +table["insert"](found, node) -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +return found -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +local function all(list, tags) -- ./compiler/lua54.can:155 +for _, node in ipairs(list) do -- ./compiler/lua54.can:156 +local ok = false -- ./compiler/lua54.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 +if node["tag"] == tag then -- ./compiler/lua54.can:159 +ok = true -- ./compiler/lua54.can:160 +break -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +if not ok then -- ./compiler/lua54.can:164 +return false -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +return true -- ./compiler/lua54.can:168 +end -- ./compiler/lua54.can:168 +local tags -- ./compiler/lua54.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 +end -- ./compiler/lua54.can:178 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 +end -- ./compiler/lua54.can:183 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local CONTINUE_START = function() -- ./compiler/lua54.can:188 +return "do" .. indent() -- ./compiler/lua54.can:189 +end -- ./compiler/lua54.can:189 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +end -- ./compiler/lua54.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 +local vars = {} -- ./compiler/lua54.can:195 +local values = {} -- ./compiler/lua54.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 +for _, v in ipairs(list) do -- ./compiler/lua54.can:198 +local var, val -- ./compiler/lua54.can:199 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 +var = v -- ./compiler/lua54.can:201 +val = { -- ./compiler/lua54.can:202 +["tag"] = "Index", -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "Id", -- ./compiler/lua54.can:202 +list["id"] -- ./compiler/lua54.can:202 +}, -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "String", -- ./compiler/lua54.can:202 +v[1] -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 +var = v[2] -- ./compiler/lua54.can:204 +val = { -- ./compiler/lua54.can:205 +["tag"] = "Index", -- ./compiler/lua54.can:205 +{ -- ./compiler/lua54.can:205 +["tag"] = "Id", -- ./compiler/lua54.can:205 +list["id"] -- ./compiler/lua54.can:205 +}, -- ./compiler/lua54.can:205 +v[1] -- ./compiler/lua54.can:205 +} -- ./compiler/lua54.can:205 +else -- ./compiler/lua54.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 +end -- ./compiler/lua54.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["rightOp"], -- ./compiler/lua54.can:210 +var, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["leftOp"], -- ./compiler/lua54.can:210 +val, -- ./compiler/lua54.can:210 +var -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 +val = { -- ./compiler/lua54.can:212 +["tag"] = "Op", -- ./compiler/lua54.can:212 +destructured["rightOp"], -- ./compiler/lua54.can:212 +var, -- ./compiler/lua54.can:212 +val -- ./compiler/lua54.can:212 +} -- ./compiler/lua54.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 +val = { -- ./compiler/lua54.can:214 +["tag"] = "Op", -- ./compiler/lua54.can:214 +destructured["leftOp"], -- ./compiler/lua54.can:214 +val, -- ./compiler/lua54.can:214 +var -- ./compiler/lua54.can:214 +} -- ./compiler/lua54.can:214 +end -- ./compiler/lua54.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +if # vars > 0 then -- ./compiler/lua54.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 +if newlineAfter then -- ./compiler/lua54.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 +else -- ./compiler/lua54.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +else -- ./compiler/lua54.can:225 +return "" -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +tags = setmetatable({ -- ./compiler/lua54.can:233 +["Block"] = function(t) -- ./compiler/lua54.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 +hasPush = false -- ./compiler/lua54.can:239 +end -- ./compiler/lua54.can:239 +local r = push("scope", {}) -- ./compiler/lua54.can:241 +if hasPush then -- ./compiler/lua54.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 +end -- ./compiler/lua54.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 +end -- ./compiler/lua54.can:246 +if t[# t] then -- ./compiler/lua54.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +end -- ./compiler/lua54.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +end -- ./compiler/lua54.can:252 +return r .. pop("scope") -- ./compiler/lua54.can:254 +end, -- ./compiler/lua54.can:254 +["Do"] = function(t) -- ./compiler/lua54.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 +end, -- ./compiler/lua54.can:261 +["Set"] = function(t) -- ./compiler/lua54.can:264 +local expr = t[# t] -- ./compiler/lua54.can:266 +local vars, values = {}, {} -- ./compiler/lua54.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 +else -- ./compiler/lua54.can:272 +table["insert"](vars, n) -- ./compiler/lua54.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 +local r = "" -- ./compiler/lua54.can:280 +if # vars > 0 then -- ./compiler/lua54.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 +end -- ./compiler/lua54.can:282 +if # destructuringVars > 0 then -- ./compiler/lua54.can:284 +local destructured = {} -- ./compiler/lua54.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 +end -- ./compiler/lua54.can:287 +return r -- ./compiler/lua54.can:289 +elseif # t == 4 then -- ./compiler/lua54.can:290 +if t[3] == "=" then -- ./compiler/lua54.can:291 +local r = "" -- ./compiler/lua54.can:292 +if # vars > 0 then -- ./compiler/lua54.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 +t[2], -- ./compiler/lua54.can:294 +vars[1], -- ./compiler/lua54.can:294 +{ -- ./compiler/lua54.can:294 +["tag"] = "Paren", -- ./compiler/lua54.can:294 +values[1] -- ./compiler/lua54.can:294 +} -- ./compiler/lua54.can:294 +}, "Op")) -- ./compiler/lua54.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 +t[2], -- ./compiler/lua54.can:296 +vars[i], -- ./compiler/lua54.can:296 +{ -- ./compiler/lua54.can:296 +["tag"] = "Paren", -- ./compiler/lua54.can:296 +values[i] -- ./compiler/lua54.can:296 +} -- ./compiler/lua54.can:296 +}, "Op")) -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +if # destructuringVars > 0 then -- ./compiler/lua54.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +end -- ./compiler/lua54.can:302 +return r -- ./compiler/lua54.can:304 +else -- ./compiler/lua54.can:304 +local r = "" -- ./compiler/lua54.can:306 +if # vars > 0 then -- ./compiler/lua54.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 +t[3], -- ./compiler/lua54.can:308 +{ -- ./compiler/lua54.can:308 +["tag"] = "Paren", -- ./compiler/lua54.can:308 +values[1] -- ./compiler/lua54.can:308 +}, -- ./compiler/lua54.can:308 +vars[1] -- ./compiler/lua54.can:308 +}, "Op")) -- ./compiler/lua54.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 +t[3], -- ./compiler/lua54.can:310 +{ -- ./compiler/lua54.can:310 +["tag"] = "Paren", -- ./compiler/lua54.can:310 +values[i] -- ./compiler/lua54.can:310 +}, -- ./compiler/lua54.can:310 +vars[i] -- ./compiler/lua54.can:310 +}, "Op")) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +if # destructuringVars > 0 then -- ./compiler/lua54.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:316 +return r -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +else -- ./compiler/lua54.can:318 +local r = "" -- ./compiler/lua54.can:321 +if # vars > 0 then -- ./compiler/lua54.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 +t[2], -- ./compiler/lua54.can:323 +vars[1], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Op", -- ./compiler/lua54.can:323 +t[4], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Paren", -- ./compiler/lua54.can:323 +values[1] -- ./compiler/lua54.can:323 +}, -- ./compiler/lua54.can:323 +vars[1] -- ./compiler/lua54.can:323 +} -- ./compiler/lua54.can:323 +}, "Op")) -- ./compiler/lua54.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 +t[2], -- ./compiler/lua54.can:325 +vars[i], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Op", -- ./compiler/lua54.can:325 +t[4], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Paren", -- ./compiler/lua54.can:325 +values[i] -- ./compiler/lua54.can:325 +}, -- ./compiler/lua54.can:325 +vars[i] -- ./compiler/lua54.can:325 +} -- ./compiler/lua54.can:325 +}, "Op")) -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +if # destructuringVars > 0 then -- ./compiler/lua54.can:328 +local destructured = { -- ./compiler/lua54.can:329 +["rightOp"] = t[2], -- ./compiler/lua54.can:329 +["leftOp"] = t[4] -- ./compiler/lua54.can:329 +} -- ./compiler/lua54.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +end -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end, -- ./compiler/lua54.can:333 +["While"] = function(t) -- ./compiler/lua54.can:337 +local r = "" -- ./compiler/lua54.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 +if # lets > 0 then -- ./compiler/lua54.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 +if # lets > 0 then -- ./compiler/lua54.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 +end -- ./compiler/lua54.can:349 +if hasContinue then -- ./compiler/lua54.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 +if hasContinue then -- ./compiler/lua54.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 +end -- ./compiler/lua54.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 +if # lets > 0 then -- ./compiler/lua54.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 +end -- ./compiler/lua54.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 +end -- ./compiler/lua54.can:363 +return r -- ./compiler/lua54.can:365 +end, -- ./compiler/lua54.can:365 +["Repeat"] = function(t) -- ./compiler/lua54.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 +local r = "repeat" .. indent() -- ./compiler/lua54.can:370 +if hasContinue then -- ./compiler/lua54.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 +end -- ./compiler/lua54.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 +if hasContinue then -- ./compiler/lua54.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 +end -- ./compiler/lua54.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 +return r -- ./compiler/lua54.can:379 +end, -- ./compiler/lua54.can:379 +["If"] = function(t) -- ./compiler/lua54.can:382 +local r = "" -- ./compiler/lua54.can:383 +local toClose = 0 -- ./compiler/lua54.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 +if # lets > 0 then -- ./compiler/lua54.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 +toClose = toClose + (1) -- ./compiler/lua54.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 +if # lets > 0 then -- ./compiler/lua54.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 +toClose = toClose + (1) -- ./compiler/lua54.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 +end -- ./compiler/lua54.can:400 +else -- ./compiler/lua54.can:400 +r = r .. ("else") -- ./compiler/lua54.can:403 +end -- ./compiler/lua54.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 +end -- ./compiler/lua54.can:405 +if # t % 2 == 1 then -- ./compiler/lua54.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +r = r .. ("end") -- ./compiler/lua54.can:410 +for i = 1, toClose do -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 +end -- ./compiler/lua54.can:412 +return r -- ./compiler/lua54.can:414 +end, -- ./compiler/lua54.can:414 +["Fornum"] = function(t) -- ./compiler/lua54.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 +if # t == 5 then -- ./compiler/lua54.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 +if hasContinue then -- ./compiler/lua54.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 +end -- ./compiler/lua54.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 +if hasContinue then -- ./compiler/lua54.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 +end -- ./compiler/lua54.can:427 +return r .. unindent() .. "end" -- ./compiler/lua54.can:429 +else -- ./compiler/lua54.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 +if hasContinue then -- ./compiler/lua54.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 +end -- ./compiler/lua54.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 +if hasContinue then -- ./compiler/lua54.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 +end -- ./compiler/lua54.can:438 +return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:440 +end, -- ./compiler/lua54.can:440 +["Forin"] = function(t) -- ./compiler/lua54.can:444 +local destructured = {} -- ./compiler/lua54.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 +if hasContinue then -- ./compiler/lua54.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 +end -- ./compiler/lua54.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 +if hasContinue then -- ./compiler/lua54.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 +end -- ./compiler/lua54.can:453 +return r .. unindent() .. "end" -- ./compiler/lua54.can:455 +end, -- ./compiler/lua54.can:455 +["Local"] = function(t) -- ./compiler/lua54.can:458 +local destructured = {} -- ./compiler/lua54.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 +if t[2][1] then -- ./compiler/lua54.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 +end -- ./compiler/lua54.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 +end, -- ./compiler/lua54.can:464 +["Let"] = function(t) -- ./compiler/lua54.can:467 +local destructured = {} -- ./compiler/lua54.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 +local r = "local " .. nameList -- ./compiler/lua54.can:470 +if t[2][1] then -- ./compiler/lua54.can:471 +if all(t[2], { -- ./compiler/lua54.can:472 +"Nil", -- ./compiler/lua54.can:472 +"Dots", -- ./compiler/lua54.can:472 +"Boolean", -- ./compiler/lua54.can:472 +"Number", -- ./compiler/lua54.can:472 +"String" -- ./compiler/lua54.can:472 +}) then -- ./compiler/lua54.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 +else -- ./compiler/lua54.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 +end, -- ./compiler/lua54.can:478 +["Localrec"] = function(t) -- ./compiler/lua54.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 +end, -- ./compiler/lua54.can:482 +["Goto"] = function(t) -- ./compiler/lua54.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Label"] = function(t) -- ./compiler/lua54.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Return"] = function(t) -- ./compiler/lua54.can:493 +local push = peek("push") -- ./compiler/lua54.can:494 +if push then -- ./compiler/lua54.can:495 +local r = "" -- ./compiler/lua54.can:496 +for _, val in ipairs(t) do -- ./compiler/lua54.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 +end -- ./compiler/lua54.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 +else -- ./compiler/lua54.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 +end -- ./compiler/lua54.can:502 +end, -- ./compiler/lua54.can:502 +["Push"] = function(t) -- ./compiler/lua54.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 +r = "" -- ./compiler/lua54.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +if t[# t] then -- ./compiler/lua54.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 +else -- ./compiler/lua54.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +return r -- ./compiler/lua54.can:519 +end, -- ./compiler/lua54.can:519 +["Break"] = function() -- ./compiler/lua54.can:522 +return "break" -- ./compiler/lua54.can:523 +end, -- ./compiler/lua54.can:523 +["Continue"] = function() -- ./compiler/lua54.can:526 +return "goto " .. var("continue") -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Nil"] = function() -- ./compiler/lua54.can:534 +return "nil" -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Dots"] = function() -- ./compiler/lua54.can:538 +return "..." -- ./compiler/lua54.can:539 +end, -- ./compiler/lua54.can:539 +["Boolean"] = function(t) -- ./compiler/lua54.can:542 +return tostring(t[1]) -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Number"] = function(t) -- ./compiler/lua54.can:546 +return tostring(t[1]) -- ./compiler/lua54.can:547 +end, -- ./compiler/lua54.can:547 +["String"] = function(t) -- ./compiler/lua54.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 +end, -- ./compiler/lua54.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 +local r = "(" -- ./compiler/lua54.can:555 +local decl = {} -- ./compiler/lua54.can:556 +if t[1][1] then -- ./compiler/lua54.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 +r = r .. (id) -- ./compiler/lua54.can:563 +else -- ./compiler/lua54.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 +end -- ./compiler/lua54.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 +r = r .. (", " .. id) -- ./compiler/lua54.can:573 +else -- ./compiler/lua54.can:573 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 +r = r .. (d .. newline()) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 +end -- ./compiler/lua54.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 +if hasPush then -- ./compiler/lua54.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 +else -- ./compiler/lua54.can:588 +push("push", false) -- ./compiler/lua54.can:590 +end -- ./compiler/lua54.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 +end -- ./compiler/lua54.can:594 +pop("push") -- ./compiler/lua54.can:596 +return r .. unindent() .. "end" -- ./compiler/lua54.can:597 +end, -- ./compiler/lua54.can:597 +["Function"] = function(t) -- ./compiler/lua54.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 +end, -- ./compiler/lua54.can:600 +["Pair"] = function(t) -- ./compiler/lua54.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 +end, -- ./compiler/lua54.can:604 +["Table"] = function(t) -- ./compiler/lua54.can:606 +if # t == 0 then -- ./compiler/lua54.can:607 +return "{}" -- ./compiler/lua54.can:608 +elseif # t == 1 then -- ./compiler/lua54.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 +else -- ./compiler/lua54.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 +end -- ./compiler/lua54.can:612 +end, -- ./compiler/lua54.can:612 +["TableCompr"] = function(t) -- ./compiler/lua54.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 +end, -- ./compiler/lua54.can:617 +["Op"] = function(t) -- ./compiler/lua54.can:620 +local r -- ./compiler/lua54.can:621 +if # t == 2 then -- ./compiler/lua54.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +else -- ./compiler/lua54.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +end -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 +else -- ./compiler/lua54.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +return r -- ./compiler/lua54.can:635 +end, -- ./compiler/lua54.can:635 +["Paren"] = function(t) -- ./compiler/lua54.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 +end, -- ./compiler/lua54.can:639 +["MethodStub"] = function(t) -- ./compiler/lua54.can:642 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 +end, -- ./compiler/lua54.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 +end, -- ./compiler/lua54.can:658 +["LetExpr"] = function(t) -- ./compiler/lua54.can:665 +return lua(t[1][1]) -- ./compiler/lua54.can:666 +end, -- ./compiler/lua54.can:666 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 +local r = "(function()" .. indent() -- ./compiler/lua54.can:672 +if hasPush then -- ./compiler/lua54.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 +else -- ./compiler/lua54.can:674 +push("push", false) -- ./compiler/lua54.can:676 +end -- ./compiler/lua54.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 +if hasPush then -- ./compiler/lua54.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 +end -- ./compiler/lua54.can:680 +pop("push") -- ./compiler/lua54.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 +return r -- ./compiler/lua54.can:684 +end, -- ./compiler/lua54.can:684 +["DoExpr"] = function(t) -- ./compiler/lua54.can:687 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 +end -- ./compiler/lua54.can:689 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 +end, -- ./compiler/lua54.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 +end, -- ./compiler/lua54.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 +end, -- ./compiler/lua54.can:699 +["IfExpr"] = function(t) -- ./compiler/lua54.can:702 +for i = 2, # t do -- ./compiler/lua54.can:703 +local block = t[i] -- ./compiler/lua54.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +end, -- ./compiler/lua54.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 +end, -- ./compiler/lua54.can:717 +["Call"] = function(t) -- ./compiler/lua54.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 +else -- ./compiler/lua54.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 +end -- ./compiler/lua54.can:730 +else -- ./compiler/lua54.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 +end -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["SafeCall"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 +else -- ./compiler/lua54.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 +end -- ./compiler/lua54.can:741 +end, -- ./compiler/lua54.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 +if start == nil then start = 1 end -- ./compiler/lua54.can:746 +local r -- ./compiler/lua54.can:747 +if t[start] then -- ./compiler/lua54.can:748 +r = lua(t[start]) -- ./compiler/lua54.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 +end -- ./compiler/lua54.can:751 +else -- ./compiler/lua54.can:751 +r = "" -- ./compiler/lua54.can:754 +end -- ./compiler/lua54.can:754 +return r -- ./compiler/lua54.can:756 +end, -- ./compiler/lua54.can:756 +["Id"] = function(t) -- ./compiler/lua54.can:759 +return t[1] -- ./compiler/lua54.can:760 +end, -- ./compiler/lua54.can:760 +["AttributeId"] = function(t) -- ./compiler/lua54.can:763 +if t[2] then -- ./compiler/lua54.can:764 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 +else -- ./compiler/lua54.can:765 +return t[1] -- ./compiler/lua54.can:767 +end -- ./compiler/lua54.can:767 +end, -- ./compiler/lua54.can:767 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 +if t["id"] then -- ./compiler/lua54.can:772 +return t["id"] -- ./compiler/lua54.can:773 +else -- ./compiler/lua54.can:773 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 +for j = 1, # t, 1 do -- ./compiler/lua54.can:777 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 +end -- ./compiler/lua54.can:778 +table["insert"](d, vars) -- ./compiler/lua54.can:780 +t["id"] = vars["id"] -- ./compiler/lua54.can:781 +return vars["id"] -- ./compiler/lua54.can:782 +end -- ./compiler/lua54.can:782 +end, -- ./compiler/lua54.can:782 +["Index"] = function(t) -- ./compiler/lua54.can:786 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 +else -- ./compiler/lua54.can:788 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +end -- ./compiler/lua54.can:790 +end, -- ./compiler/lua54.can:790 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 +local l = {} -- ./compiler/lua54.can:796 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 +table["insert"](l, 1, t) -- ./compiler/lua54.can:798 +t = t[1] -- ./compiler/lua54.can:799 +end -- ./compiler/lua54.can:799 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 +for _, e in ipairs(l) do -- ./compiler/lua54.can:802 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 +else -- ./compiler/lua54.can:805 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 +return r -- ./compiler/lua54.can:811 +else -- ./compiler/lua54.can:811 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 +end -- ./compiler/lua54.can:813 +end, -- ./compiler/lua54.can:813 +["_opid"] = { -- ./compiler/lua54.can:818 +["add"] = "+", -- ./compiler/lua54.can:819 +["sub"] = "-", -- ./compiler/lua54.can:819 +["mul"] = "*", -- ./compiler/lua54.can:819 +["div"] = "/", -- ./compiler/lua54.can:819 +["idiv"] = "//", -- ./compiler/lua54.can:820 +["mod"] = "%", -- ./compiler/lua54.can:820 +["pow"] = "^", -- ./compiler/lua54.can:820 +["concat"] = "..", -- ./compiler/lua54.can:820 +["band"] = "&", -- ./compiler/lua54.can:821 +["bor"] = "|", -- ./compiler/lua54.can:821 +["bxor"] = "~", -- ./compiler/lua54.can:821 +["shl"] = "<<", -- ./compiler/lua54.can:821 +["shr"] = ">>", -- ./compiler/lua54.can:821 +["eq"] = "==", -- ./compiler/lua54.can:822 +["ne"] = "~=", -- ./compiler/lua54.can:822 +["lt"] = "<", -- ./compiler/lua54.can:822 +["gt"] = ">", -- ./compiler/lua54.can:822 +["le"] = "<=", -- ./compiler/lua54.can:822 +["ge"] = ">=", -- ./compiler/lua54.can:822 +["and"] = "and", -- ./compiler/lua54.can:823 +["or"] = "or", -- ./compiler/lua54.can:823 +["unm"] = "-", -- ./compiler/lua54.can:823 +["len"] = "#", -- ./compiler/lua54.can:823 +["bnot"] = "~", -- ./compiler/lua54.can:823 +["not"] = "not" -- ./compiler/lua54.can:823 +} -- ./compiler/lua54.can:823 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 +end }) -- ./compiler/lua54.can:827 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 +return requireStr .. code -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +return lua54 -- ./compiler/lua53.can:10 +end -- ./compiler/lua53.can:10 +local lua53 = _() or lua53 -- ./compiler/lua53.can:14 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 @@ -1879,914 +2733,872 @@ package["loaded"]["compiler.luajit"] = luajit or true -- ./compiler/luajit.can:4 local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 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 -- ./compiler/lua53.can:5 -local prevLinePos = 1 -- ./compiler/lua53.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua53.can:7 -local lastLine = 1 -- ./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 function _() -- ./compiler/luajit.can:58 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +return function(code, ast, options) -- ./compiler/lua54.can:3 +local lastInputPos = 1 -- ./compiler/lua54.can:5 +local prevLinePos = 1 -- ./compiler/lua54.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 +local lastLine = 1 -- ./compiler/lua54.can:8 +local indentLevel = 0 -- ./compiler/lua54.can:11 +local function newline() -- ./compiler/lua54.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 +if options["mapLines"] then -- ./compiler/lua54.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./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 +") -- ./compiler/lua54.can:17 +if source and line then -- ./compiler/lua54.can:19 +lastSource = source -- ./compiler/lua54.can:20 +lastLine = tonumber(line) -- ./compiler/lua54.can:21 +else -- ./compiler/lua54.can:21 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") 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 -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 states = { -- ./compiler/lua53.can:47 -["push"] = {}, -- ./compiler/lua53.can:48 -["destructuring"] = {}, -- ./compiler/lua53.can:49 -["scope"] = {} -- ./compiler/lua53.can:50 -} -- ./compiler/lua53.can:50 -local function push(name, state) -- ./compiler/lua53.can:53 -table["insert"](states[name], state) -- ./compiler/lua53.can:54 -return "" -- ./compiler/lua53.can:55 -end -- ./compiler/lua53.can:55 -local function pop(name) -- ./compiler/lua53.can:58 -table["remove"](states[name]) -- ./compiler/lua53.can:59 -return "" -- ./compiler/lua53.can:60 -end -- ./compiler/lua53.can:60 -local function set(name, state) -- ./compiler/lua53.can:63 -states[name][# states[name]] = state -- ./compiler/lua53.can:64 -return "" -- ./compiler/lua53.can:65 -end -- ./compiler/lua53.can:65 -local function peek(name) -- ./compiler/lua53.can:68 -return states[name][# states[name]] -- ./compiler/lua53.can:69 -end -- ./compiler/lua53.can:69 -local function var(name) -- ./compiler/lua53.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua53.can:75 -end -- ./compiler/lua53.can:75 -local function tmp() -- ./compiler/lua53.can:79 -local scope = peek("scope") -- ./compiler/lua53.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua53.can:81 -table["insert"](scope, var) -- ./compiler/lua53.can:82 -return var -- ./compiler/lua53.can:83 -end -- ./compiler/lua53.can:83 -local required = {} -- ./compiler/lua53.can:87 -local requireStr = "" -- ./compiler/lua53.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua53.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua53.can:91 -if not required[req] then -- ./compiler/lua53.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua53.can:93 -required[req] = true -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -end -- ./compiler/lua53.can:94 -local loop = { -- ./compiler/lua53.can:99 -"While", -- ./compiler/lua53.can:99 -"Repeat", -- ./compiler/lua53.can:99 -"Fornum", -- ./compiler/lua53.can:99 -"Forin", -- ./compiler/lua53.can:99 -"WhileExpr", -- ./compiler/lua53.can:99 -"RepeatExpr", -- ./compiler/lua53.can:99 -"FornumExpr", -- ./compiler/lua53.can:99 -"ForinExpr" -- ./compiler/lua53.can:99 -} -- ./compiler/lua53.can:99 -local func = { -- ./compiler/lua53.can:100 -"Function", -- ./compiler/lua53.can:100 -"TableCompr", -- ./compiler/lua53.can:100 -"DoExpr", -- ./compiler/lua53.can:100 -"WhileExpr", -- ./compiler/lua53.can:100 -"RepeatExpr", -- ./compiler/lua53.can:100 -"IfExpr", -- ./compiler/lua53.can:100 -"FornumExpr", -- ./compiler/lua53.can:100 -"ForinExpr" -- ./compiler/lua53.can:100 -} -- ./compiler/lua53.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua53.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:104 -local tagsCheck = {} -- ./compiler/lua53.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:106 -tagsCheck[tag] = true -- ./compiler/lua53.can:107 -end -- ./compiler/lua53.can:107 -local nofollowCheck = {} -- ./compiler/lua53.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:110 -nofollowCheck[tag] = true -- ./compiler/lua53.can:111 -end -- ./compiler/lua53.can:111 -for _, node in ipairs(list) do -- ./compiler/lua53.can:113 -if type(node) == "table" then -- ./compiler/lua53.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:115 -return node -- ./compiler/lua53.can:116 -end -- ./compiler/lua53.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua53.can:119 -if r then -- ./compiler/lua53.can:120 -return r -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -end -- ./compiler/lua53.can:120 -return nil -- ./compiler/lua53.can:124 -end -- ./compiler/lua53.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua53.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua53.can:129 -local tagsCheck = {} -- ./compiler/lua53.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:131 -tagsCheck[tag] = true -- ./compiler/lua53.can:132 -end -- ./compiler/lua53.can:132 -local nofollowCheck = {} -- ./compiler/lua53.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua53.can:135 -nofollowCheck[tag] = true -- ./compiler/lua53.can:136 -end -- ./compiler/lua53.can:136 -local found = {} -- ./compiler/lua53.can:138 -for _, node in ipairs(list) do -- ./compiler/lua53.can:139 -if type(node) == "table" then -- ./compiler/lua53.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua53.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua53.can:142 -table["insert"](found, n) -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -end -- ./compiler/lua53.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua53.can:146 -table["insert"](found, node) -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -end -- ./compiler/lua53.can:147 -return found -- ./compiler/lua53.can:151 -end -- ./compiler/lua53.can:151 -local function all(list, tags) -- ./compiler/lua53.can:155 -for _, node in ipairs(list) do -- ./compiler/lua53.can:156 -local ok = false -- ./compiler/lua53.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua53.can:158 -if node["tag"] == tag then -- ./compiler/lua53.can:159 -ok = true -- ./compiler/lua53.can:160 -break -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -end -- ./compiler/lua53.can:161 -if not ok then -- ./compiler/lua53.can:164 -return false -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -end -- ./compiler/lua53.can:165 -return true -- ./compiler/lua53.can:168 -end -- ./compiler/lua53.can:168 -local tags -- ./compiler/lua53.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua53.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua53.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua53.can:176 -end -- ./compiler/lua53.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua53.can:178 -end -- ./compiler/lua53.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua53.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua53.can:183 -end -- ./compiler/lua53.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua53.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua53.can:186 -end -- ./compiler/lua53.can:186 -local CONTINUE_START = function() -- ./compiler/lua53.can:188 -return "do" .. indent() -- ./compiler/lua53.can:189 -end -- ./compiler/lua53.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua53.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua53.can:192 -end -- ./compiler/lua53.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua53.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua53.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua53.can:194 -local vars = {} -- ./compiler/lua53.can:195 -local values = {} -- ./compiler/lua53.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua53.can:197 -for _, v in ipairs(list) do -- ./compiler/lua53.can:198 -local var, val -- ./compiler/lua53.can:199 -if v["tag"] == "Id" then -- ./compiler/lua53.can:200 -var = v -- ./compiler/lua53.can:201 -val = { -- ./compiler/lua53.can:202 -["tag"] = "Index", -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "Id", -- ./compiler/lua53.can:202 -list["id"] -- ./compiler/lua53.can:202 -}, -- ./compiler/lua53.can:202 -{ -- ./compiler/lua53.can:202 -["tag"] = "String", -- ./compiler/lua53.can:202 -v[1] -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -} -- ./compiler/lua53.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua53.can:203 -var = v[2] -- ./compiler/lua53.can:204 -val = { -- ./compiler/lua53.can:205 -["tag"] = "Index", -- ./compiler/lua53.can:205 -{ -- ./compiler/lua53.can:205 -["tag"] = "Id", -- ./compiler/lua53.can:205 -list["id"] -- ./compiler/lua53.can:205 -}, -- ./compiler/lua53.can:205 -v[1] -- ./compiler/lua53.can:205 -} -- ./compiler/lua53.can:205 -else -- ./compiler/lua53.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua53.can:207 -end -- ./compiler/lua53.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua53.can:209 -val = { -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["rightOp"], -- ./compiler/lua53.can:210 -var, -- ./compiler/lua53.can:210 -{ -- ./compiler/lua53.can:210 -["tag"] = "Op", -- ./compiler/lua53.can:210 -destructured["leftOp"], -- ./compiler/lua53.can:210 -val, -- ./compiler/lua53.can:210 -var -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -} -- ./compiler/lua53.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua53.can:211 -val = { -- ./compiler/lua53.can:212 -["tag"] = "Op", -- ./compiler/lua53.can:212 -destructured["rightOp"], -- ./compiler/lua53.can:212 -var, -- ./compiler/lua53.can:212 -val -- ./compiler/lua53.can:212 -} -- ./compiler/lua53.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua53.can:213 -val = { -- ./compiler/lua53.can:214 -["tag"] = "Op", -- ./compiler/lua53.can:214 -destructured["leftOp"], -- ./compiler/lua53.can:214 -val, -- ./compiler/lua53.can:214 -var -- ./compiler/lua53.can:214 -} -- ./compiler/lua53.can:214 -end -- ./compiler/lua53.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua53.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -end -- ./compiler/lua53.can:217 -if # vars > 0 then -- ./compiler/lua53.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua53.can:221 -if newlineAfter then -- ./compiler/lua53.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua53.can:223 -else -- ./compiler/lua53.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua53.can:225 -end -- ./compiler/lua53.can:225 -else -- ./compiler/lua53.can:225 -return "" -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -end -- ./compiler/lua53.can:228 -tags = setmetatable({ -- ./compiler/lua53.can:233 -["Block"] = function(t) -- ./compiler/lua53.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua53.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua53.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua53.can:238 -hasPush = false -- ./compiler/lua53.can:239 -end -- ./compiler/lua53.can:239 -local r = push("scope", {}) -- ./compiler/lua53.can:241 -if hasPush then -- ./compiler/lua53.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:243 -end -- ./compiler/lua53.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua53.can:246 -end -- ./compiler/lua53.can:246 -if t[# t] then -- ./compiler/lua53.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua53.can:249 -end -- ./compiler/lua53.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua53.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua53.can:252 -end -- ./compiler/lua53.can:252 -return r .. pop("scope") -- ./compiler/lua53.can:254 -end, -- ./compiler/lua53.can:254 -["Do"] = function(t) -- ./compiler/lua53.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua53.can:261 -end, -- ./compiler/lua53.can:261 -["Set"] = function(t) -- ./compiler/lua53.can:264 -local expr = t[# t] -- ./compiler/lua53.can:266 -local vars, values = {}, {} -- ./compiler/lua53.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua53.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua53.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua53.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua53.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua53.can:272 -else -- ./compiler/lua53.can:272 -table["insert"](vars, n) -- ./compiler/lua53.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -end -- ./compiler/lua53.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua53.can:279 -local r = "" -- ./compiler/lua53.can:280 -if # vars > 0 then -- ./compiler/lua53.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua53.can:282 -end -- ./compiler/lua53.can:282 -if # destructuringVars > 0 then -- ./compiler/lua53.can:284 -local destructured = {} -- ./compiler/lua53.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:287 -end -- ./compiler/lua53.can:287 -return r -- ./compiler/lua53.can:289 -elseif # t == 4 then -- ./compiler/lua53.can:290 -if t[3] == "=" then -- ./compiler/lua53.can:291 -local r = "" -- ./compiler/lua53.can:292 -if # vars > 0 then -- ./compiler/lua53.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:294 -t[2], -- ./compiler/lua53.can:294 -vars[1], -- ./compiler/lua53.can:294 -{ -- ./compiler/lua53.can:294 -["tag"] = "Paren", -- ./compiler/lua53.can:294 -values[1] -- ./compiler/lua53.can:294 -} -- ./compiler/lua53.can:294 -}, "Op")) -- ./compiler/lua53.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua53.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:296 -t[2], -- ./compiler/lua53.can:296 -vars[i], -- ./compiler/lua53.can:296 -{ -- ./compiler/lua53.can:296 -["tag"] = "Paren", -- ./compiler/lua53.can:296 -values[i] -- ./compiler/lua53.can:296 -} -- ./compiler/lua53.can:296 -}, "Op")) -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -end -- ./compiler/lua53.can:296 -if # destructuringVars > 0 then -- ./compiler/lua53.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua53.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:302 -end -- ./compiler/lua53.can:302 -return r -- ./compiler/lua53.can:304 -else -- ./compiler/lua53.can:304 -local r = "" -- ./compiler/lua53.can:306 -if # vars > 0 then -- ./compiler/lua53.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:308 -t[3], -- ./compiler/lua53.can:308 -{ -- ./compiler/lua53.can:308 -["tag"] = "Paren", -- ./compiler/lua53.can:308 -values[1] -- ./compiler/lua53.can:308 -}, -- ./compiler/lua53.can:308 -vars[1] -- ./compiler/lua53.can:308 -}, "Op")) -- ./compiler/lua53.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua53.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:310 -t[3], -- ./compiler/lua53.can:310 -{ -- ./compiler/lua53.can:310 -["tag"] = "Paren", -- ./compiler/lua53.can:310 -values[i] -- ./compiler/lua53.can:310 -}, -- ./compiler/lua53.can:310 -vars[i] -- ./compiler/lua53.can:310 -}, "Op")) -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -end -- ./compiler/lua53.can:310 -if # destructuringVars > 0 then -- ./compiler/lua53.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua53.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:316 -end -- ./compiler/lua53.can:316 -return r -- ./compiler/lua53.can:318 -end -- ./compiler/lua53.can:318 -else -- ./compiler/lua53.can:318 -local r = "" -- ./compiler/lua53.can:321 -if # vars > 0 then -- ./compiler/lua53.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua53.can:323 -t[2], -- ./compiler/lua53.can:323 -vars[1], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Op", -- ./compiler/lua53.can:323 -t[4], -- ./compiler/lua53.can:323 -{ -- ./compiler/lua53.can:323 -["tag"] = "Paren", -- ./compiler/lua53.can:323 -values[1] -- ./compiler/lua53.can:323 -}, -- ./compiler/lua53.can:323 -vars[1] -- ./compiler/lua53.can:323 -} -- ./compiler/lua53.can:323 -}, "Op")) -- ./compiler/lua53.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua53.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua53.can:325 -t[2], -- ./compiler/lua53.can:325 -vars[i], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Op", -- ./compiler/lua53.can:325 -t[4], -- ./compiler/lua53.can:325 -{ -- ./compiler/lua53.can:325 -["tag"] = "Paren", -- ./compiler/lua53.can:325 -values[i] -- ./compiler/lua53.can:325 -}, -- ./compiler/lua53.can:325 -vars[i] -- ./compiler/lua53.can:325 -} -- ./compiler/lua53.can:325 -}, "Op")) -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -end -- ./compiler/lua53.can:325 -if # destructuringVars > 0 then -- ./compiler/lua53.can:328 -local destructured = { -- ./compiler/lua53.can:329 -["rightOp"] = t[2], -- ./compiler/lua53.can:329 -["leftOp"] = t[4] -- ./compiler/lua53.can:329 -} -- ./compiler/lua53.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua53.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua53.can:331 -end -- ./compiler/lua53.can:331 -return r -- ./compiler/lua53.can:333 -end -- ./compiler/lua53.can:333 -end, -- ./compiler/lua53.can:333 -["While"] = function(t) -- ./compiler/lua53.can:337 -local r = "" -- ./compiler/lua53.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua53.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:340 -if # lets > 0 then -- ./compiler/lua53.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -end -- ./compiler/lua53.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua53.can:347 -if # lets > 0 then -- ./compiler/lua53.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:349 -end -- ./compiler/lua53.can:349 -if hasContinue then -- ./compiler/lua53.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:352 -end -- ./compiler/lua53.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:354 -if hasContinue then -- ./compiler/lua53.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:356 -end -- ./compiler/lua53.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:358 -if # lets > 0 then -- ./compiler/lua53.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua53.can:361 -end -- ./compiler/lua53.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua53.can:363 -end -- ./compiler/lua53.can:363 -return r -- ./compiler/lua53.can:365 -end, -- ./compiler/lua53.can:365 -["Repeat"] = function(t) -- ./compiler/lua53.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua53.can:369 -local r = "repeat" .. indent() -- ./compiler/lua53.can:370 -if hasContinue then -- ./compiler/lua53.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:372 -end -- ./compiler/lua53.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua53.can:374 -if hasContinue then -- ./compiler/lua53.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:376 -end -- ./compiler/lua53.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua53.can:378 -return r -- ./compiler/lua53.can:379 -end, -- ./compiler/lua53.can:379 -["If"] = function(t) -- ./compiler/lua53.can:382 -local r = "" -- ./compiler/lua53.can:383 -local toClose = 0 -- ./compiler/lua53.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua53.can:385 -if # lets > 0 then -- ./compiler/lua53.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua53.can:387 -toClose = toClose + (1) -- ./compiler/lua53.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -end -- ./compiler/lua53.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua53.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua53.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua53.can:395 -if # lets > 0 then -- ./compiler/lua53.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua53.can:397 -toClose = toClose + (1) -- ./compiler/lua53.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua53.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua53.can:400 -end -- ./compiler/lua53.can:400 -else -- ./compiler/lua53.can:400 -r = r .. ("else") -- ./compiler/lua53.can:403 -end -- ./compiler/lua53.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua53.can:405 -end -- ./compiler/lua53.can:405 -if # t % 2 == 1 then -- ./compiler/lua53.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua53.can:408 -end -- ./compiler/lua53.can:408 -r = r .. ("end") -- ./compiler/lua53.can:410 -for i = 1, toClose do -- ./compiler/lua53.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua53.can:412 -end -- ./compiler/lua53.can:412 -return r -- ./compiler/lua53.can:414 -end, -- ./compiler/lua53.can:414 -["Fornum"] = function(t) -- ./compiler/lua53.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua53.can:418 -if # t == 5 then -- ./compiler/lua53.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua53.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua53.can:421 -if hasContinue then -- ./compiler/lua53.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:423 -end -- ./compiler/lua53.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua53.can:425 -if hasContinue then -- ./compiler/lua53.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:427 -end -- ./compiler/lua53.can:427 -return r .. unindent() .. "end" -- ./compiler/lua53.can:429 -else -- ./compiler/lua53.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua53.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua53.can:432 -if hasContinue then -- ./compiler/lua53.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:434 -end -- ./compiler/lua53.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua53.can:436 -if hasContinue then -- ./compiler/lua53.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:438 -end -- ./compiler/lua53.can:438 -return r .. unindent() .. "end" -- ./compiler/lua53.can:440 -end -- ./compiler/lua53.can:440 -end, -- ./compiler/lua53.can:440 -["Forin"] = function(t) -- ./compiler/lua53.can:444 -local destructured = {} -- ./compiler/lua53.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua53.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua53.can:447 -if hasContinue then -- ./compiler/lua53.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua53.can:449 -end -- ./compiler/lua53.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua53.can:451 -if hasContinue then -- ./compiler/lua53.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua53.can:453 -end -- ./compiler/lua53.can:453 -return r .. unindent() .. "end" -- ./compiler/lua53.can:455 -end, -- ./compiler/lua53.can:455 -["Local"] = function(t) -- ./compiler/lua53.can:458 -local destructured = {} -- ./compiler/lua53.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:460 -if t[2][1] then -- ./compiler/lua53.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:462 -end -- ./compiler/lua53.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:464 -end, -- ./compiler/lua53.can:464 -["Let"] = function(t) -- ./compiler/lua53.can:467 -local destructured = {} -- ./compiler/lua53.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua53.can:469 -local r = "local " .. nameList -- ./compiler/lua53.can:470 -if t[2][1] then -- ./compiler/lua53.can:471 -if all(t[2], { -- ./compiler/lua53.can:472 -"Nil", -- ./compiler/lua53.can:472 -"Dots", -- ./compiler/lua53.can:472 -"Boolean", -- ./compiler/lua53.can:472 -"Number", -- ./compiler/lua53.can:472 -"String" -- ./compiler/lua53.can:472 -}) then -- ./compiler/lua53.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:473 -else -- ./compiler/lua53.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -end -- ./compiler/lua53.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua53.can:478 -end, -- ./compiler/lua53.can:478 -["Localrec"] = function(t) -- ./compiler/lua53.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua53.can:482 -end, -- ./compiler/lua53.can:482 -["Goto"] = function(t) -- ./compiler/lua53.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua53.can:486 -end, -- ./compiler/lua53.can:486 -["Label"] = function(t) -- ./compiler/lua53.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua53.can:490 -end, -- ./compiler/lua53.can:490 -["Return"] = function(t) -- ./compiler/lua53.can:493 -local push = peek("push") -- ./compiler/lua53.can:494 -if push then -- ./compiler/lua53.can:495 -local r = "" -- ./compiler/lua53.can:496 -for _, val in ipairs(t) do -- ./compiler/lua53.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua53.can:498 -end -- ./compiler/lua53.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua53.can:500 -else -- ./compiler/lua53.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua53.can:502 -end -- ./compiler/lua53.can:502 -end, -- ./compiler/lua53.can:502 -["Push"] = function(t) -- ./compiler/lua53.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua53.can:507 -r = "" -- ./compiler/lua53.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua53.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua53.can:510 -end -- ./compiler/lua53.can:510 -if t[# t] then -- ./compiler/lua53.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua53.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua53.can:514 -else -- ./compiler/lua53.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -end -- ./compiler/lua53.can:516 -return r -- ./compiler/lua53.can:519 -end, -- ./compiler/lua53.can:519 -["Break"] = function() -- ./compiler/lua53.can:522 -return "break" -- ./compiler/lua53.can:523 -end, -- ./compiler/lua53.can:523 -["Continue"] = function() -- ./compiler/lua53.can:526 -return "goto " .. var("continue") -- ./compiler/lua53.can:527 -end, -- ./compiler/lua53.can:527 -["Nil"] = function() -- ./compiler/lua53.can:534 -return "nil" -- ./compiler/lua53.can:535 -end, -- ./compiler/lua53.can:535 -["Dots"] = function() -- ./compiler/lua53.can:538 -return "..." -- ./compiler/lua53.can:539 -end, -- ./compiler/lua53.can:539 -["Boolean"] = function(t) -- ./compiler/lua53.can:542 -return tostring(t[1]) -- ./compiler/lua53.can:543 -end, -- ./compiler/lua53.can:543 -["Number"] = function(t) -- ./compiler/lua53.can:546 -return tostring(t[1]) -- ./compiler/lua53.can:547 -end, -- ./compiler/lua53.can:547 -["String"] = function(t) -- ./compiler/lua53.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua53.can:551 -end, -- ./compiler/lua53.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua53.can:554 -local r = "(" -- ./compiler/lua53.can:555 -local decl = {} -- ./compiler/lua53.can:556 -if t[1][1] then -- ./compiler/lua53.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua53.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua53.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua53.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:562 -r = r .. (id) -- ./compiler/lua53.can:563 -else -- ./compiler/lua53.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua53.can:565 -end -- ./compiler/lua53.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua53.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua53.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua53.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua53.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua53.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua53.can:572 -r = r .. (", " .. id) -- ./compiler/lua53.can:573 -else -- ./compiler/lua53.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -end -- ./compiler/lua53.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua53.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua53.can:580 -r = r .. (d .. newline()) -- ./compiler/lua53.can:581 -end -- ./compiler/lua53.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua53.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua53.can:584 -end -- ./compiler/lua53.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua53.can:586 -if hasPush then -- ./compiler/lua53.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:588 -else -- ./compiler/lua53.can:588 -push("push", false) -- ./compiler/lua53.can:590 -end -- ./compiler/lua53.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua53.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua53.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:594 -end -- ./compiler/lua53.can:594 -pop("push") -- ./compiler/lua53.can:596 -return r .. unindent() .. "end" -- ./compiler/lua53.can:597 -end, -- ./compiler/lua53.can:597 -["Function"] = function(t) -- ./compiler/lua53.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua53.can:600 -end, -- ./compiler/lua53.can:600 -["Pair"] = function(t) -- ./compiler/lua53.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua53.can:604 -end, -- ./compiler/lua53.can:604 -["Table"] = function(t) -- ./compiler/lua53.can:606 -if # t == 0 then -- ./compiler/lua53.can:607 -return "{}" -- ./compiler/lua53.can:608 -elseif # t == 1 then -- ./compiler/lua53.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua53.can:610 -else -- ./compiler/lua53.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua53.can:612 -end -- ./compiler/lua53.can:612 -end, -- ./compiler/lua53.can:612 -["TableCompr"] = function(t) -- ./compiler/lua53.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua53.can:617 -end, -- ./compiler/lua53.can:617 -["Op"] = function(t) -- ./compiler/lua53.can:620 -local r -- ./compiler/lua53.can:621 -if # t == 2 then -- ./compiler/lua53.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua53.can:624 -else -- ./compiler/lua53.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua53.can:626 -end -- ./compiler/lua53.can:626 -else -- ./compiler/lua53.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua53.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua53.can:630 -else -- ./compiler/lua53.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -end -- ./compiler/lua53.can:632 -return r -- ./compiler/lua53.can:635 -end, -- ./compiler/lua53.can:635 -["Paren"] = function(t) -- ./compiler/lua53.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua53.can:639 -end, -- ./compiler/lua53.can:639 -["MethodStub"] = function(t) -- ./compiler/lua53.can:642 -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:648 -end, -- ./compiler/lua53.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua53.can:651 -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:658 -end, -- ./compiler/lua53.can:658 -["LetExpr"] = function(t) -- ./compiler/lua53.can:665 -return lua(t[1][1]) -- ./compiler/lua53.can:666 -end, -- ./compiler/lua53.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua53.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua53.can:671 -local r = "(function()" .. indent() -- ./compiler/lua53.can:672 -if hasPush then -- ./compiler/lua53.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua53.can:674 -else -- ./compiler/lua53.can:674 -push("push", false) -- ./compiler/lua53.can:676 -end -- ./compiler/lua53.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua53.can:678 -if hasPush then -- ./compiler/lua53.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua53.can:680 -end -- ./compiler/lua53.can:680 -pop("push") -- ./compiler/lua53.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua53.can:683 -return r -- ./compiler/lua53.can:684 -end, -- ./compiler/lua53.can:684 -["DoExpr"] = function(t) -- ./compiler/lua53.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua53.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua53.can:689 -end -- ./compiler/lua53.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua53.can:691 -end, -- ./compiler/lua53.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua53.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua53.can:695 -end, -- ./compiler/lua53.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua53.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua53.can:699 -end, -- ./compiler/lua53.can:699 -["IfExpr"] = function(t) -- ./compiler/lua53.can:702 -for i = 2, # t do -- ./compiler/lua53.can:703 -local block = t[i] -- ./compiler/lua53.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua53.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -end -- ./compiler/lua53.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua53.can:709 -end, -- ./compiler/lua53.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua53.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua53.can:713 -end, -- ./compiler/lua53.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua53.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua53.can:717 -end, -- ./compiler/lua53.can:717 -["Call"] = function(t) -- ./compiler/lua53.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua53.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua53.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:728 -else -- ./compiler/lua53.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:730 -end -- ./compiler/lua53.can:730 -else -- ./compiler/lua53.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua53.can:733 -end -- ./compiler/lua53.can:733 -end, -- ./compiler/lua53.can:733 -["SafeCall"] = function(t) -- ./compiler/lua53.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua53.can:739 -else -- ./compiler/lua53.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua53.can:741 -end -- ./compiler/lua53.can:741 -end, -- ./compiler/lua53.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua53.can:746 -if start == nil then start = 1 end -- ./compiler/lua53.can:746 -local r -- ./compiler/lua53.can:747 -if t[start] then -- ./compiler/lua53.can:748 -r = lua(t[start]) -- ./compiler/lua53.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua53.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua53.can:751 -end -- ./compiler/lua53.can:751 -else -- ./compiler/lua53.can:751 -r = "" -- ./compiler/lua53.can:754 -end -- ./compiler/lua53.can:754 -return r -- ./compiler/lua53.can:756 -end, -- ./compiler/lua53.can:756 -["Id"] = function(t) -- ./compiler/lua53.can:759 -return t[1] -- ./compiler/lua53.can:760 -end, -- ./compiler/lua53.can:760 -["DestructuringId"] = function(t) -- ./compiler/lua53.can:763 -if t["id"] then -- ./compiler/lua53.can:764 -return t["id"] -- ./compiler/lua53.can:765 -else -- ./compiler/lua53.can:765 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua53.can:767 -local vars = { ["id"] = tmp() } -- ./compiler/lua53.can:768 -for j = 1, # t, 1 do -- ./compiler/lua53.can:769 -table["insert"](vars, t[j]) -- ./compiler/lua53.can:770 -end -- ./compiler/lua53.can:770 -table["insert"](d, vars) -- ./compiler/lua53.can:772 -t["id"] = vars["id"] -- ./compiler/lua53.can:773 -return vars["id"] -- ./compiler/lua53.can:774 -end -- ./compiler/lua53.can:774 -end, -- ./compiler/lua53.can:774 -["Index"] = function(t) -- ./compiler/lua53.can:778 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua53.can:779 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:780 -else -- ./compiler/lua53.can:780 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua53.can:782 -end -- ./compiler/lua53.can:782 -end, -- ./compiler/lua53.can:782 -["SafeIndex"] = function(t) -- ./compiler/lua53.can:786 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua53.can:787 -local l = {} -- ./compiler/lua53.can:788 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua53.can:789 -table["insert"](l, 1, t) -- ./compiler/lua53.can:790 -t = t[1] -- ./compiler/lua53.can:791 -end -- ./compiler/lua53.can:791 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua53.can:793 -for _, e in ipairs(l) do -- ./compiler/lua53.can:794 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua53.can:795 -if e["tag"] == "SafeIndex" then -- ./compiler/lua53.can:796 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua53.can:797 -else -- ./compiler/lua53.can:797 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -end -- ./compiler/lua53.can:799 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua53.can:802 -return r -- ./compiler/lua53.can:803 -else -- ./compiler/lua53.can:803 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua53.can:805 -end -- ./compiler/lua53.can:805 -end, -- ./compiler/lua53.can:805 -["_opid"] = { -- ./compiler/lua53.can:810 -["add"] = "+", -- ./compiler/lua53.can:811 -["sub"] = "-", -- ./compiler/lua53.can:811 -["mul"] = "*", -- ./compiler/lua53.can:811 -["div"] = "/", -- ./compiler/lua53.can:811 -["idiv"] = "//", -- ./compiler/lua53.can:812 -["mod"] = "%", -- ./compiler/lua53.can:812 -["pow"] = "^", -- ./compiler/lua53.can:812 -["concat"] = "..", -- ./compiler/lua53.can:812 -["band"] = "&", -- ./compiler/lua53.can:813 -["bor"] = "|", -- ./compiler/lua53.can:813 -["bxor"] = "~", -- ./compiler/lua53.can:813 -["shl"] = "<<", -- ./compiler/lua53.can:813 -["shr"] = ">>", -- ./compiler/lua53.can:813 -["eq"] = "==", -- ./compiler/lua53.can:814 -["ne"] = "~=", -- ./compiler/lua53.can:814 -["lt"] = "<", -- ./compiler/lua53.can:814 -["gt"] = ">", -- ./compiler/lua53.can:814 -["le"] = "<=", -- ./compiler/lua53.can:814 -["ge"] = ">=", -- ./compiler/lua53.can:814 -["and"] = "and", -- ./compiler/lua53.can:815 -["or"] = "or", -- ./compiler/lua53.can:815 -["unm"] = "-", -- ./compiler/lua53.can:815 -["len"] = "#", -- ./compiler/lua53.can:815 -["bnot"] = "~", -- ./compiler/lua53.can:815 -["not"] = "not" -- ./compiler/lua53.can:815 -} -- ./compiler/lua53.can:815 -}, { ["__index"] = function(self, key) -- ./compiler/lua53.can:818 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua53.can:819 -end }) -- ./compiler/lua53.can:819 -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 " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/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"] = {} -- ./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:825 -return requireStr .. code -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -end -- ./compiler/lua53.can:826 -local lua53 = _() or lua53 -- ./compiler/lua53.can:831 +") do -- ./compiler/lua54.can:23 +lastLine = lastLine + (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +prevLinePos = lastInputPos -- ./compiler/lua54.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 +end -- ./compiler/lua54.can:30 +return r -- ./compiler/lua54.can:32 +end -- ./compiler/lua54.can:32 +local function indent() -- ./compiler/lua54.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 +return newline() -- ./compiler/lua54.can:37 +end -- ./compiler/lua54.can:37 +local function unindent() -- ./compiler/lua54.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 +return newline() -- ./compiler/lua54.can:42 +end -- ./compiler/lua54.can:42 +local states = { -- ./compiler/lua54.can:47 +["push"] = {}, -- ./compiler/lua54.can:48 +["destructuring"] = {}, -- ./compiler/lua54.can:49 +["scope"] = {} -- ./compiler/lua54.can:50 +} -- ./compiler/lua54.can:50 +local function push(name, state) -- ./compiler/lua54.can:53 +table["insert"](states[name], state) -- ./compiler/lua54.can:54 +return "" -- ./compiler/lua54.can:55 +end -- ./compiler/lua54.can:55 +local function pop(name) -- ./compiler/lua54.can:58 +table["remove"](states[name]) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function set(name, state) -- ./compiler/lua54.can:63 +states[name][# states[name]] = state -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function peek(name) -- ./compiler/lua54.can:68 +return states[name][# states[name]] -- ./compiler/lua54.can:69 +end -- ./compiler/lua54.can:69 +local function var(name) -- ./compiler/lua54.can:74 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 +end -- ./compiler/lua54.can:75 +local function tmp() -- ./compiler/lua54.can:79 +local scope = peek("scope") -- ./compiler/lua54.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 +table["insert"](scope, var) -- ./compiler/lua54.can:82 +return var -- ./compiler/lua54.can:83 +end -- ./compiler/lua54.can:83 +local required = {} -- ./compiler/lua54.can:87 +local requireStr = "" -- ./compiler/lua54.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 +if not required[req] then -- ./compiler/lua54.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 +required[req] = true -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +local loop = { -- ./compiler/lua54.can:99 +"While", -- ./compiler/lua54.can:99 +"Repeat", -- ./compiler/lua54.can:99 +"Fornum", -- ./compiler/lua54.can:99 +"Forin", -- ./compiler/lua54.can:99 +"WhileExpr", -- ./compiler/lua54.can:99 +"RepeatExpr", -- ./compiler/lua54.can:99 +"FornumExpr", -- ./compiler/lua54.can:99 +"ForinExpr" -- ./compiler/lua54.can:99 +} -- ./compiler/lua54.can:99 +local func = { -- ./compiler/lua54.can:100 +"Function", -- ./compiler/lua54.can:100 +"TableCompr", -- ./compiler/lua54.can:100 +"DoExpr", -- ./compiler/lua54.can:100 +"WhileExpr", -- ./compiler/lua54.can:100 +"RepeatExpr", -- ./compiler/lua54.can:100 +"IfExpr", -- ./compiler/lua54.can:100 +"FornumExpr", -- ./compiler/lua54.can:100 +"ForinExpr" -- ./compiler/lua54.can:100 +} -- ./compiler/lua54.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 +local tagsCheck = {} -- ./compiler/lua54.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 +tagsCheck[tag] = true -- ./compiler/lua54.can:107 +end -- ./compiler/lua54.can:107 +local nofollowCheck = {} -- ./compiler/lua54.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 +nofollowCheck[tag] = true -- ./compiler/lua54.can:111 +end -- ./compiler/lua54.can:111 +for _, node in ipairs(list) do -- ./compiler/lua54.can:113 +if type(node) == "table" then -- ./compiler/lua54.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 +return node -- ./compiler/lua54.can:116 +end -- ./compiler/lua54.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 +if r then -- ./compiler/lua54.can:120 +return r -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +return nil -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 +local tagsCheck = {} -- ./compiler/lua54.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 +tagsCheck[tag] = true -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local nofollowCheck = {} -- ./compiler/lua54.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 +nofollowCheck[tag] = true -- ./compiler/lua54.can:136 +end -- ./compiler/lua54.can:136 +local found = {} -- ./compiler/lua54.can:138 +for _, node in ipairs(list) do -- ./compiler/lua54.can:139 +if type(node) == "table" then -- ./compiler/lua54.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 +table["insert"](found, n) -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 +table["insert"](found, node) -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +return found -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +local function all(list, tags) -- ./compiler/lua54.can:155 +for _, node in ipairs(list) do -- ./compiler/lua54.can:156 +local ok = false -- ./compiler/lua54.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 +if node["tag"] == tag then -- ./compiler/lua54.can:159 +ok = true -- ./compiler/lua54.can:160 +break -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +if not ok then -- ./compiler/lua54.can:164 +return false -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +return true -- ./compiler/lua54.can:168 +end -- ./compiler/lua54.can:168 +local tags -- ./compiler/lua54.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 +end -- ./compiler/lua54.can:178 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 +end -- ./compiler/lua54.can:183 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local CONTINUE_START = function() -- ./compiler/lua54.can:188 +return "do" .. indent() -- ./compiler/lua54.can:189 +end -- ./compiler/lua54.can:189 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +end -- ./compiler/lua54.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 +local vars = {} -- ./compiler/lua54.can:195 +local values = {} -- ./compiler/lua54.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 +for _, v in ipairs(list) do -- ./compiler/lua54.can:198 +local var, val -- ./compiler/lua54.can:199 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 +var = v -- ./compiler/lua54.can:201 +val = { -- ./compiler/lua54.can:202 +["tag"] = "Index", -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "Id", -- ./compiler/lua54.can:202 +list["id"] -- ./compiler/lua54.can:202 +}, -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "String", -- ./compiler/lua54.can:202 +v[1] -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 +var = v[2] -- ./compiler/lua54.can:204 +val = { -- ./compiler/lua54.can:205 +["tag"] = "Index", -- ./compiler/lua54.can:205 +{ -- ./compiler/lua54.can:205 +["tag"] = "Id", -- ./compiler/lua54.can:205 +list["id"] -- ./compiler/lua54.can:205 +}, -- ./compiler/lua54.can:205 +v[1] -- ./compiler/lua54.can:205 +} -- ./compiler/lua54.can:205 +else -- ./compiler/lua54.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 +end -- ./compiler/lua54.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["rightOp"], -- ./compiler/lua54.can:210 +var, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["leftOp"], -- ./compiler/lua54.can:210 +val, -- ./compiler/lua54.can:210 +var -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 +val = { -- ./compiler/lua54.can:212 +["tag"] = "Op", -- ./compiler/lua54.can:212 +destructured["rightOp"], -- ./compiler/lua54.can:212 +var, -- ./compiler/lua54.can:212 +val -- ./compiler/lua54.can:212 +} -- ./compiler/lua54.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 +val = { -- ./compiler/lua54.can:214 +["tag"] = "Op", -- ./compiler/lua54.can:214 +destructured["leftOp"], -- ./compiler/lua54.can:214 +val, -- ./compiler/lua54.can:214 +var -- ./compiler/lua54.can:214 +} -- ./compiler/lua54.can:214 +end -- ./compiler/lua54.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +if # vars > 0 then -- ./compiler/lua54.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 +if newlineAfter then -- ./compiler/lua54.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 +else -- ./compiler/lua54.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +else -- ./compiler/lua54.can:225 +return "" -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +tags = setmetatable({ -- ./compiler/lua54.can:233 +["Block"] = function(t) -- ./compiler/lua54.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 +hasPush = false -- ./compiler/lua54.can:239 +end -- ./compiler/lua54.can:239 +local r = push("scope", {}) -- ./compiler/lua54.can:241 +if hasPush then -- ./compiler/lua54.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 +end -- ./compiler/lua54.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 +end -- ./compiler/lua54.can:246 +if t[# t] then -- ./compiler/lua54.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +end -- ./compiler/lua54.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +end -- ./compiler/lua54.can:252 +return r .. pop("scope") -- ./compiler/lua54.can:254 +end, -- ./compiler/lua54.can:254 +["Do"] = function(t) -- ./compiler/lua54.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 +end, -- ./compiler/lua54.can:261 +["Set"] = function(t) -- ./compiler/lua54.can:264 +local expr = t[# t] -- ./compiler/lua54.can:266 +local vars, values = {}, {} -- ./compiler/lua54.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 +else -- ./compiler/lua54.can:272 +table["insert"](vars, n) -- ./compiler/lua54.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 +local r = "" -- ./compiler/lua54.can:280 +if # vars > 0 then -- ./compiler/lua54.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 +end -- ./compiler/lua54.can:282 +if # destructuringVars > 0 then -- ./compiler/lua54.can:284 +local destructured = {} -- ./compiler/lua54.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 +end -- ./compiler/lua54.can:287 +return r -- ./compiler/lua54.can:289 +elseif # t == 4 then -- ./compiler/lua54.can:290 +if t[3] == "=" then -- ./compiler/lua54.can:291 +local r = "" -- ./compiler/lua54.can:292 +if # vars > 0 then -- ./compiler/lua54.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 +t[2], -- ./compiler/lua54.can:294 +vars[1], -- ./compiler/lua54.can:294 +{ -- ./compiler/lua54.can:294 +["tag"] = "Paren", -- ./compiler/lua54.can:294 +values[1] -- ./compiler/lua54.can:294 +} -- ./compiler/lua54.can:294 +}, "Op")) -- ./compiler/lua54.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 +t[2], -- ./compiler/lua54.can:296 +vars[i], -- ./compiler/lua54.can:296 +{ -- ./compiler/lua54.can:296 +["tag"] = "Paren", -- ./compiler/lua54.can:296 +values[i] -- ./compiler/lua54.can:296 +} -- ./compiler/lua54.can:296 +}, "Op")) -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +if # destructuringVars > 0 then -- ./compiler/lua54.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +end -- ./compiler/lua54.can:302 +return r -- ./compiler/lua54.can:304 +else -- ./compiler/lua54.can:304 +local r = "" -- ./compiler/lua54.can:306 +if # vars > 0 then -- ./compiler/lua54.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 +t[3], -- ./compiler/lua54.can:308 +{ -- ./compiler/lua54.can:308 +["tag"] = "Paren", -- ./compiler/lua54.can:308 +values[1] -- ./compiler/lua54.can:308 +}, -- ./compiler/lua54.can:308 +vars[1] -- ./compiler/lua54.can:308 +}, "Op")) -- ./compiler/lua54.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 +t[3], -- ./compiler/lua54.can:310 +{ -- ./compiler/lua54.can:310 +["tag"] = "Paren", -- ./compiler/lua54.can:310 +values[i] -- ./compiler/lua54.can:310 +}, -- ./compiler/lua54.can:310 +vars[i] -- ./compiler/lua54.can:310 +}, "Op")) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +if # destructuringVars > 0 then -- ./compiler/lua54.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:316 +return r -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +else -- ./compiler/lua54.can:318 +local r = "" -- ./compiler/lua54.can:321 +if # vars > 0 then -- ./compiler/lua54.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 +t[2], -- ./compiler/lua54.can:323 +vars[1], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Op", -- ./compiler/lua54.can:323 +t[4], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Paren", -- ./compiler/lua54.can:323 +values[1] -- ./compiler/lua54.can:323 +}, -- ./compiler/lua54.can:323 +vars[1] -- ./compiler/lua54.can:323 +} -- ./compiler/lua54.can:323 +}, "Op")) -- ./compiler/lua54.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 +t[2], -- ./compiler/lua54.can:325 +vars[i], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Op", -- ./compiler/lua54.can:325 +t[4], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Paren", -- ./compiler/lua54.can:325 +values[i] -- ./compiler/lua54.can:325 +}, -- ./compiler/lua54.can:325 +vars[i] -- ./compiler/lua54.can:325 +} -- ./compiler/lua54.can:325 +}, "Op")) -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +if # destructuringVars > 0 then -- ./compiler/lua54.can:328 +local destructured = { -- ./compiler/lua54.can:329 +["rightOp"] = t[2], -- ./compiler/lua54.can:329 +["leftOp"] = t[4] -- ./compiler/lua54.can:329 +} -- ./compiler/lua54.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +end -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end, -- ./compiler/lua54.can:333 +["While"] = function(t) -- ./compiler/lua54.can:337 +local r = "" -- ./compiler/lua54.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 +if # lets > 0 then -- ./compiler/lua54.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 +if # lets > 0 then -- ./compiler/lua54.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 +end -- ./compiler/lua54.can:349 +if hasContinue then -- ./compiler/lua54.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 +if hasContinue then -- ./compiler/lua54.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 +end -- ./compiler/lua54.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 +if # lets > 0 then -- ./compiler/lua54.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 +end -- ./compiler/lua54.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 +end -- ./compiler/lua54.can:363 +return r -- ./compiler/lua54.can:365 +end, -- ./compiler/lua54.can:365 +["Repeat"] = function(t) -- ./compiler/lua54.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 +local r = "repeat" .. indent() -- ./compiler/lua54.can:370 +if hasContinue then -- ./compiler/lua54.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 +end -- ./compiler/lua54.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 +if hasContinue then -- ./compiler/lua54.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 +end -- ./compiler/lua54.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 +return r -- ./compiler/lua54.can:379 +end, -- ./compiler/lua54.can:379 +["If"] = function(t) -- ./compiler/lua54.can:382 +local r = "" -- ./compiler/lua54.can:383 +local toClose = 0 -- ./compiler/lua54.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 +if # lets > 0 then -- ./compiler/lua54.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 +toClose = toClose + (1) -- ./compiler/lua54.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 +if # lets > 0 then -- ./compiler/lua54.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 +toClose = toClose + (1) -- ./compiler/lua54.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 +end -- ./compiler/lua54.can:400 +else -- ./compiler/lua54.can:400 +r = r .. ("else") -- ./compiler/lua54.can:403 +end -- ./compiler/lua54.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 +end -- ./compiler/lua54.can:405 +if # t % 2 == 1 then -- ./compiler/lua54.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +r = r .. ("end") -- ./compiler/lua54.can:410 +for i = 1, toClose do -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 +end -- ./compiler/lua54.can:412 +return r -- ./compiler/lua54.can:414 +end, -- ./compiler/lua54.can:414 +["Fornum"] = function(t) -- ./compiler/lua54.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 +if # t == 5 then -- ./compiler/lua54.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 +if hasContinue then -- ./compiler/lua54.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 +end -- ./compiler/lua54.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 +if hasContinue then -- ./compiler/lua54.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 +end -- ./compiler/lua54.can:427 +return r .. unindent() .. "end" -- ./compiler/lua54.can:429 +else -- ./compiler/lua54.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 +if hasContinue then -- ./compiler/lua54.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 +end -- ./compiler/lua54.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 +if hasContinue then -- ./compiler/lua54.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 +end -- ./compiler/lua54.can:438 +return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:440 +end, -- ./compiler/lua54.can:440 +["Forin"] = function(t) -- ./compiler/lua54.can:444 +local destructured = {} -- ./compiler/lua54.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 +if hasContinue then -- ./compiler/lua54.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 +end -- ./compiler/lua54.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 +if hasContinue then -- ./compiler/lua54.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 +end -- ./compiler/lua54.can:453 +return r .. unindent() .. "end" -- ./compiler/lua54.can:455 +end, -- ./compiler/lua54.can:455 +["Local"] = function(t) -- ./compiler/lua54.can:458 +local destructured = {} -- ./compiler/lua54.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 +if t[2][1] then -- ./compiler/lua54.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 +end -- ./compiler/lua54.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 +end, -- ./compiler/lua54.can:464 +["Let"] = function(t) -- ./compiler/lua54.can:467 +local destructured = {} -- ./compiler/lua54.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 +local r = "local " .. nameList -- ./compiler/lua54.can:470 +if t[2][1] then -- ./compiler/lua54.can:471 +if all(t[2], { -- ./compiler/lua54.can:472 +"Nil", -- ./compiler/lua54.can:472 +"Dots", -- ./compiler/lua54.can:472 +"Boolean", -- ./compiler/lua54.can:472 +"Number", -- ./compiler/lua54.can:472 +"String" -- ./compiler/lua54.can:472 +}) then -- ./compiler/lua54.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 +else -- ./compiler/lua54.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 +end, -- ./compiler/lua54.can:478 +["Localrec"] = function(t) -- ./compiler/lua54.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 +end, -- ./compiler/lua54.can:482 +["Goto"] = function(t) -- ./compiler/lua54.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Label"] = function(t) -- ./compiler/lua54.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Return"] = function(t) -- ./compiler/lua54.can:493 +local push = peek("push") -- ./compiler/lua54.can:494 +if push then -- ./compiler/lua54.can:495 +local r = "" -- ./compiler/lua54.can:496 +for _, val in ipairs(t) do -- ./compiler/lua54.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 +end -- ./compiler/lua54.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 +else -- ./compiler/lua54.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 +end -- ./compiler/lua54.can:502 +end, -- ./compiler/lua54.can:502 +["Push"] = function(t) -- ./compiler/lua54.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 +r = "" -- ./compiler/lua54.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +if t[# t] then -- ./compiler/lua54.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 +else -- ./compiler/lua54.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +return r -- ./compiler/lua54.can:519 +end, -- ./compiler/lua54.can:519 +["Break"] = function() -- ./compiler/lua54.can:522 +return "break" -- ./compiler/lua54.can:523 +end, -- ./compiler/lua54.can:523 +["Continue"] = function() -- ./compiler/lua54.can:526 +return "goto " .. var("continue") -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Nil"] = function() -- ./compiler/lua54.can:534 +return "nil" -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Dots"] = function() -- ./compiler/lua54.can:538 +return "..." -- ./compiler/lua54.can:539 +end, -- ./compiler/lua54.can:539 +["Boolean"] = function(t) -- ./compiler/lua54.can:542 +return tostring(t[1]) -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Number"] = function(t) -- ./compiler/lua54.can:546 +return tostring(t[1]) -- ./compiler/lua54.can:547 +end, -- ./compiler/lua54.can:547 +["String"] = function(t) -- ./compiler/lua54.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 +end, -- ./compiler/lua54.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 +local r = "(" -- ./compiler/lua54.can:555 +local decl = {} -- ./compiler/lua54.can:556 +if t[1][1] then -- ./compiler/lua54.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 +r = r .. (id) -- ./compiler/lua54.can:563 +else -- ./compiler/lua54.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 +end -- ./compiler/lua54.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 +r = r .. (", " .. id) -- ./compiler/lua54.can:573 +else -- ./compiler/lua54.can:573 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 +r = r .. (d .. newline()) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 +end -- ./compiler/lua54.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 +if hasPush then -- ./compiler/lua54.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 +else -- ./compiler/lua54.can:588 +push("push", false) -- ./compiler/lua54.can:590 +end -- ./compiler/lua54.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 +end -- ./compiler/lua54.can:594 +pop("push") -- ./compiler/lua54.can:596 +return r .. unindent() .. "end" -- ./compiler/lua54.can:597 +end, -- ./compiler/lua54.can:597 +["Function"] = function(t) -- ./compiler/lua54.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 +end, -- ./compiler/lua54.can:600 +["Pair"] = function(t) -- ./compiler/lua54.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 +end, -- ./compiler/lua54.can:604 +["Table"] = function(t) -- ./compiler/lua54.can:606 +if # t == 0 then -- ./compiler/lua54.can:607 +return "{}" -- ./compiler/lua54.can:608 +elseif # t == 1 then -- ./compiler/lua54.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 +else -- ./compiler/lua54.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 +end -- ./compiler/lua54.can:612 +end, -- ./compiler/lua54.can:612 +["TableCompr"] = function(t) -- ./compiler/lua54.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 +end, -- ./compiler/lua54.can:617 +["Op"] = function(t) -- ./compiler/lua54.can:620 +local r -- ./compiler/lua54.can:621 +if # t == 2 then -- ./compiler/lua54.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +else -- ./compiler/lua54.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +end -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 +else -- ./compiler/lua54.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +return r -- ./compiler/lua54.can:635 +end, -- ./compiler/lua54.can:635 +["Paren"] = function(t) -- ./compiler/lua54.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 +end, -- ./compiler/lua54.can:639 +["MethodStub"] = function(t) -- ./compiler/lua54.can:642 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 +end, -- ./compiler/lua54.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 +end, -- ./compiler/lua54.can:658 +["LetExpr"] = function(t) -- ./compiler/lua54.can:665 +return lua(t[1][1]) -- ./compiler/lua54.can:666 +end, -- ./compiler/lua54.can:666 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 +local r = "(function()" .. indent() -- ./compiler/lua54.can:672 +if hasPush then -- ./compiler/lua54.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 +else -- ./compiler/lua54.can:674 +push("push", false) -- ./compiler/lua54.can:676 +end -- ./compiler/lua54.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 +if hasPush then -- ./compiler/lua54.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 +end -- ./compiler/lua54.can:680 +pop("push") -- ./compiler/lua54.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 +return r -- ./compiler/lua54.can:684 +end, -- ./compiler/lua54.can:684 +["DoExpr"] = function(t) -- ./compiler/lua54.can:687 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 +end -- ./compiler/lua54.can:689 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 +end, -- ./compiler/lua54.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 +end, -- ./compiler/lua54.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 +end, -- ./compiler/lua54.can:699 +["IfExpr"] = function(t) -- ./compiler/lua54.can:702 +for i = 2, # t do -- ./compiler/lua54.can:703 +local block = t[i] -- ./compiler/lua54.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +end, -- ./compiler/lua54.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 +end, -- ./compiler/lua54.can:717 +["Call"] = function(t) -- ./compiler/lua54.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 +else -- ./compiler/lua54.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 +end -- ./compiler/lua54.can:730 +else -- ./compiler/lua54.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 +end -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["SafeCall"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 +else -- ./compiler/lua54.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 +end -- ./compiler/lua54.can:741 +end, -- ./compiler/lua54.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 +if start == nil then start = 1 end -- ./compiler/lua54.can:746 +local r -- ./compiler/lua54.can:747 +if t[start] then -- ./compiler/lua54.can:748 +r = lua(t[start]) -- ./compiler/lua54.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 +end -- ./compiler/lua54.can:751 +else -- ./compiler/lua54.can:751 +r = "" -- ./compiler/lua54.can:754 +end -- ./compiler/lua54.can:754 +return r -- ./compiler/lua54.can:756 +end, -- ./compiler/lua54.can:756 +["Id"] = function(t) -- ./compiler/lua54.can:759 +return t[1] -- ./compiler/lua54.can:760 +end, -- ./compiler/lua54.can:760 +["AttributeId"] = function(t) -- ./compiler/lua54.can:763 +if t[2] then -- ./compiler/lua54.can:764 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 +else -- ./compiler/lua54.can:765 +return t[1] -- ./compiler/lua54.can:767 +end -- ./compiler/lua54.can:767 +end, -- ./compiler/lua54.can:767 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 +if t["id"] then -- ./compiler/lua54.can:772 +return t["id"] -- ./compiler/lua54.can:773 +else -- ./compiler/lua54.can:773 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 +for j = 1, # t, 1 do -- ./compiler/lua54.can:777 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 +end -- ./compiler/lua54.can:778 +table["insert"](d, vars) -- ./compiler/lua54.can:780 +t["id"] = vars["id"] -- ./compiler/lua54.can:781 +return vars["id"] -- ./compiler/lua54.can:782 +end -- ./compiler/lua54.can:782 +end, -- ./compiler/lua54.can:782 +["Index"] = function(t) -- ./compiler/lua54.can:786 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 +else -- ./compiler/lua54.can:788 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +end -- ./compiler/lua54.can:790 +end, -- ./compiler/lua54.can:790 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 +local l = {} -- ./compiler/lua54.can:796 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 +table["insert"](l, 1, t) -- ./compiler/lua54.can:798 +t = t[1] -- ./compiler/lua54.can:799 +end -- ./compiler/lua54.can:799 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 +for _, e in ipairs(l) do -- ./compiler/lua54.can:802 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 +else -- ./compiler/lua54.can:805 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 +return r -- ./compiler/lua54.can:811 +else -- ./compiler/lua54.can:811 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 +end -- ./compiler/lua54.can:813 +end, -- ./compiler/lua54.can:813 +["_opid"] = { -- ./compiler/lua54.can:818 +["add"] = "+", -- ./compiler/lua54.can:819 +["sub"] = "-", -- ./compiler/lua54.can:819 +["mul"] = "*", -- ./compiler/lua54.can:819 +["div"] = "/", -- ./compiler/lua54.can:819 +["idiv"] = "//", -- ./compiler/lua54.can:820 +["mod"] = "%", -- ./compiler/lua54.can:820 +["pow"] = "^", -- ./compiler/lua54.can:820 +["concat"] = "..", -- ./compiler/lua54.can:820 +["band"] = "&", -- ./compiler/lua54.can:821 +["bor"] = "|", -- ./compiler/lua54.can:821 +["bxor"] = "~", -- ./compiler/lua54.can:821 +["shl"] = "<<", -- ./compiler/lua54.can:821 +["shr"] = ">>", -- ./compiler/lua54.can:821 +["eq"] = "==", -- ./compiler/lua54.can:822 +["ne"] = "~=", -- ./compiler/lua54.can:822 +["lt"] = "<", -- ./compiler/lua54.can:822 +["gt"] = ">", -- ./compiler/lua54.can:822 +["le"] = "<=", -- ./compiler/lua54.can:822 +["ge"] = ">=", -- ./compiler/lua54.can:822 +["and"] = "and", -- ./compiler/lua54.can:823 +["or"] = "or", -- ./compiler/lua54.can:823 +["unm"] = "-", -- ./compiler/lua54.can:823 +["len"] = "#", -- ./compiler/lua54.can:823 +["bnot"] = "~", -- ./compiler/lua54.can:823 +["not"] = "not" -- ./compiler/lua54.can:823 +} -- ./compiler/lua54.can:823 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 +end }) -- ./compiler/lua54.can:827 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 +return requireStr .. code -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +return lua54 -- ./compiler/lua53.can:10 +end -- ./compiler/lua53.can:10 +local lua53 = _() or lua53 -- ./compiler/lua53.can:14 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 @@ -3798,933 +4610,977 @@ local labels = { -- ./candran/can-parser/parser.lua:88 }, -- ./candran/can-parser/parser.lua:115 { -- ./candran/can-parser/parser.lua:116 "ErrDefLet", -- ./candran/can-parser/parser.lua:116 -"expected a function definition or assignment after let" -- ./candran/can-parser/parser.lua:116 +"expected an assignment after let" -- ./candran/can-parser/parser.lua:116 }, -- ./candran/can-parser/parser.lua:116 { -- ./candran/can-parser/parser.lua:117 -"ErrNameLFunc", -- ./candran/can-parser/parser.lua:117 -"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:117 +"ErrDefClose", -- ./candran/can-parser/parser.lua:117 +"expected an assignment after close" -- ./candran/can-parser/parser.lua:117 }, -- ./candran/can-parser/parser.lua:117 { -- ./candran/can-parser/parser.lua:118 -"ErrEListLAssign", -- ./candran/can-parser/parser.lua:118 -"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:118 +"ErrDefConst", -- ./candran/can-parser/parser.lua:118 +"expected an assignment after const" -- ./candran/can-parser/parser.lua:118 }, -- ./candran/can-parser/parser.lua:118 { -- ./candran/can-parser/parser.lua:119 -"ErrEListAssign", -- ./candran/can-parser/parser.lua:119 -"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:119 +"ErrNameLFunc", -- ./candran/can-parser/parser.lua:119 +"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:119 }, -- ./candran/can-parser/parser.lua:119 +{ -- ./candran/can-parser/parser.lua:120 +"ErrEListLAssign", -- ./candran/can-parser/parser.lua:120 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:120 +}, -- ./candran/can-parser/parser.lua:120 { -- ./candran/can-parser/parser.lua:121 -"ErrFuncName", -- ./candran/can-parser/parser.lua:121 -"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:121 +"ErrEListAssign", -- ./candran/can-parser/parser.lua:121 +"expected one or more expressions after '='" -- ./candran/can-parser/parser.lua:121 }, -- ./candran/can-parser/parser.lua:121 -{ -- ./candran/can-parser/parser.lua:122 -"ErrNameFunc1", -- ./candran/can-parser/parser.lua:122 -"expected a function name after '.'" -- ./candran/can-parser/parser.lua:122 -}, -- ./candran/can-parser/parser.lua:122 { -- ./candran/can-parser/parser.lua:123 -"ErrNameFunc2", -- ./candran/can-parser/parser.lua:123 -"expected a method name after ':'" -- ./candran/can-parser/parser.lua:123 +"ErrFuncName", -- ./candran/can-parser/parser.lua:123 +"expected a function name after 'function'" -- ./candran/can-parser/parser.lua:123 }, -- ./candran/can-parser/parser.lua:123 { -- ./candran/can-parser/parser.lua:124 -"ErrOParenPList", -- ./candran/can-parser/parser.lua:124 -"expected '(' for the parameter list" -- ./candran/can-parser/parser.lua:124 +"ErrNameFunc1", -- ./candran/can-parser/parser.lua:124 +"expected a function name after '.'" -- ./candran/can-parser/parser.lua:124 }, -- ./candran/can-parser/parser.lua:124 { -- ./candran/can-parser/parser.lua:125 -"ErrCParenPList", -- ./candran/can-parser/parser.lua:125 -"expected ')' to close the parameter list" -- ./candran/can-parser/parser.lua:125 +"ErrNameFunc2", -- ./candran/can-parser/parser.lua:125 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:125 }, -- ./candran/can-parser/parser.lua:125 { -- ./candran/can-parser/parser.lua:126 -"ErrEndFunc", -- ./candran/can-parser/parser.lua:126 -"expected 'end' to close the function body" -- ./candran/can-parser/parser.lua:126 +"ErrOParenPList", -- ./candran/can-parser/parser.lua:126 +"expected '(' for the parameter list" -- ./candran/can-parser/parser.lua:126 }, -- ./candran/can-parser/parser.lua:126 { -- ./candran/can-parser/parser.lua:127 -"ErrParList", -- ./candran/can-parser/parser.lua:127 -"expected a variable name or '...' after ','" -- ./candran/can-parser/parser.lua:127 +"ErrCParenPList", -- ./candran/can-parser/parser.lua:127 +"expected ')' to close the parameter list" -- ./candran/can-parser/parser.lua:127 }, -- ./candran/can-parser/parser.lua:127 +{ -- ./candran/can-parser/parser.lua:128 +"ErrEndFunc", -- ./candran/can-parser/parser.lua:128 +"expected 'end' to close the function body" -- ./candran/can-parser/parser.lua:128 +}, -- ./candran/can-parser/parser.lua:128 { -- ./candran/can-parser/parser.lua:129 -"ErrLabel", -- ./candran/can-parser/parser.lua:129 -"expected a label name after '::'" -- ./candran/can-parser/parser.lua:129 +"ErrParList", -- ./candran/can-parser/parser.lua:129 +"expected a variable name or '...' after ','" -- ./candran/can-parser/parser.lua:129 }, -- ./candran/can-parser/parser.lua:129 -{ -- ./candran/can-parser/parser.lua:130 -"ErrCloseLabel", -- ./candran/can-parser/parser.lua:130 -"expected '::' after the label" -- ./candran/can-parser/parser.lua:130 -}, -- ./candran/can-parser/parser.lua:130 { -- ./candran/can-parser/parser.lua:131 -"ErrGoto", -- ./candran/can-parser/parser.lua:131 -"expected a label after 'goto'" -- ./candran/can-parser/parser.lua:131 +"ErrLabel", -- ./candran/can-parser/parser.lua:131 +"expected a label name after '::'" -- ./candran/can-parser/parser.lua:131 }, -- ./candran/can-parser/parser.lua:131 { -- ./candran/can-parser/parser.lua:132 -"ErrRetList", -- ./candran/can-parser/parser.lua:132 -"expected an expression after ',' in the return statement" -- ./candran/can-parser/parser.lua:132 +"ErrCloseLabel", -- ./candran/can-parser/parser.lua:132 +"expected '::' after the label" -- ./candran/can-parser/parser.lua:132 }, -- ./candran/can-parser/parser.lua:132 +{ -- ./candran/can-parser/parser.lua:133 +"ErrGoto", -- ./candran/can-parser/parser.lua:133 +"expected a label after 'goto'" -- ./candran/can-parser/parser.lua:133 +}, -- ./candran/can-parser/parser.lua:133 { -- ./candran/can-parser/parser.lua:134 -"ErrVarList", -- ./candran/can-parser/parser.lua:134 -"expected a variable name after ','" -- ./candran/can-parser/parser.lua:134 +"ErrRetList", -- ./candran/can-parser/parser.lua:134 +"expected an expression after ',' in the return statement" -- ./candran/can-parser/parser.lua:134 }, -- ./candran/can-parser/parser.lua:134 -{ -- ./candran/can-parser/parser.lua:135 -"ErrExprList", -- ./candran/can-parser/parser.lua:135 -"expected an expression after ','" -- ./candran/can-parser/parser.lua:135 -}, -- ./candran/can-parser/parser.lua:135 +{ -- ./candran/can-parser/parser.lua:136 +"ErrVarList", -- ./candran/can-parser/parser.lua:136 +"expected a variable name after ','" -- ./candran/can-parser/parser.lua:136 +}, -- ./candran/can-parser/parser.lua:136 { -- ./candran/can-parser/parser.lua:137 -"ErrOrExpr", -- ./candran/can-parser/parser.lua:137 -"expected an expression after 'or'" -- ./candran/can-parser/parser.lua:137 +"ErrExprList", -- ./candran/can-parser/parser.lua:137 +"expected an expression after ','" -- ./candran/can-parser/parser.lua:137 }, -- ./candran/can-parser/parser.lua:137 -{ -- ./candran/can-parser/parser.lua:138 -"ErrAndExpr", -- ./candran/can-parser/parser.lua:138 -"expected an expression after 'and'" -- ./candran/can-parser/parser.lua:138 -}, -- ./candran/can-parser/parser.lua:138 { -- ./candran/can-parser/parser.lua:139 -"ErrRelExpr", -- ./candran/can-parser/parser.lua:139 -"expected an expression after the relational operator" -- ./candran/can-parser/parser.lua:139 +"ErrOrExpr", -- ./candran/can-parser/parser.lua:139 +"expected an expression after 'or'" -- ./candran/can-parser/parser.lua:139 }, -- ./candran/can-parser/parser.lua:139 { -- ./candran/can-parser/parser.lua:140 -"ErrBOrExpr", -- ./candran/can-parser/parser.lua:140 -"expected an expression after '|'" -- ./candran/can-parser/parser.lua:140 +"ErrAndExpr", -- ./candran/can-parser/parser.lua:140 +"expected an expression after 'and'" -- ./candran/can-parser/parser.lua:140 }, -- ./candran/can-parser/parser.lua:140 { -- ./candran/can-parser/parser.lua:141 -"ErrBXorExpr", -- ./candran/can-parser/parser.lua:141 -"expected an expression after '~'" -- ./candran/can-parser/parser.lua:141 +"ErrRelExpr", -- ./candran/can-parser/parser.lua:141 +"expected an expression after the relational operator" -- ./candran/can-parser/parser.lua:141 }, -- ./candran/can-parser/parser.lua:141 { -- ./candran/can-parser/parser.lua:142 -"ErrBAndExpr", -- ./candran/can-parser/parser.lua:142 -"expected an expression after '&'" -- ./candran/can-parser/parser.lua:142 +"ErrBOrExpr", -- ./candran/can-parser/parser.lua:142 +"expected an expression after '|'" -- ./candran/can-parser/parser.lua:142 }, -- ./candran/can-parser/parser.lua:142 { -- ./candran/can-parser/parser.lua:143 -"ErrShiftExpr", -- ./candran/can-parser/parser.lua:143 -"expected an expression after the bit shift" -- ./candran/can-parser/parser.lua:143 +"ErrBXorExpr", -- ./candran/can-parser/parser.lua:143 +"expected an expression after '~'" -- ./candran/can-parser/parser.lua:143 }, -- ./candran/can-parser/parser.lua:143 { -- ./candran/can-parser/parser.lua:144 -"ErrConcatExpr", -- ./candran/can-parser/parser.lua:144 -"expected an expression after '..'" -- ./candran/can-parser/parser.lua:144 +"ErrBAndExpr", -- ./candran/can-parser/parser.lua:144 +"expected an expression after '&'" -- ./candran/can-parser/parser.lua:144 }, -- ./candran/can-parser/parser.lua:144 { -- ./candran/can-parser/parser.lua:145 -"ErrAddExpr", -- ./candran/can-parser/parser.lua:145 -"expected an expression after the additive operator" -- ./candran/can-parser/parser.lua:145 +"ErrShiftExpr", -- ./candran/can-parser/parser.lua:145 +"expected an expression after the bit shift" -- ./candran/can-parser/parser.lua:145 }, -- ./candran/can-parser/parser.lua:145 { -- ./candran/can-parser/parser.lua:146 -"ErrMulExpr", -- ./candran/can-parser/parser.lua:146 -"expected an expression after the multiplicative operator" -- ./candran/can-parser/parser.lua:146 +"ErrConcatExpr", -- ./candran/can-parser/parser.lua:146 +"expected an expression after '..'" -- ./candran/can-parser/parser.lua:146 }, -- ./candran/can-parser/parser.lua:146 { -- ./candran/can-parser/parser.lua:147 -"ErrUnaryExpr", -- ./candran/can-parser/parser.lua:147 -"expected an expression after the unary operator" -- ./candran/can-parser/parser.lua:147 +"ErrAddExpr", -- ./candran/can-parser/parser.lua:147 +"expected an expression after the additive operator" -- ./candran/can-parser/parser.lua:147 }, -- ./candran/can-parser/parser.lua:147 { -- ./candran/can-parser/parser.lua:148 -"ErrPowExpr", -- ./candran/can-parser/parser.lua:148 -"expected an expression after '^'" -- ./candran/can-parser/parser.lua:148 +"ErrMulExpr", -- ./candran/can-parser/parser.lua:148 +"expected an expression after the multiplicative operator" -- ./candran/can-parser/parser.lua:148 }, -- ./candran/can-parser/parser.lua:148 +{ -- ./candran/can-parser/parser.lua:149 +"ErrUnaryExpr", -- ./candran/can-parser/parser.lua:149 +"expected an expression after the unary operator" -- ./candran/can-parser/parser.lua:149 +}, -- ./candran/can-parser/parser.lua:149 { -- ./candran/can-parser/parser.lua:150 -"ErrExprParen", -- ./candran/can-parser/parser.lua:150 -"expected an expression after '('" -- ./candran/can-parser/parser.lua:150 +"ErrPowExpr", -- ./candran/can-parser/parser.lua:150 +"expected an expression after '^'" -- ./candran/can-parser/parser.lua:150 }, -- ./candran/can-parser/parser.lua:150 -{ -- ./candran/can-parser/parser.lua:151 -"ErrCParenExpr", -- ./candran/can-parser/parser.lua:151 -"expected ')' to close the expression" -- ./candran/can-parser/parser.lua:151 -}, -- ./candran/can-parser/parser.lua:151 { -- ./candran/can-parser/parser.lua:152 -"ErrNameIndex", -- ./candran/can-parser/parser.lua:152 -"expected a field name after '.'" -- ./candran/can-parser/parser.lua:152 +"ErrExprParen", -- ./candran/can-parser/parser.lua:152 +"expected an expression after '('" -- ./candran/can-parser/parser.lua:152 }, -- ./candran/can-parser/parser.lua:152 { -- ./candran/can-parser/parser.lua:153 -"ErrExprIndex", -- ./candran/can-parser/parser.lua:153 -"expected an expression after '['" -- ./candran/can-parser/parser.lua:153 +"ErrCParenExpr", -- ./candran/can-parser/parser.lua:153 +"expected ')' to close the expression" -- ./candran/can-parser/parser.lua:153 }, -- ./candran/can-parser/parser.lua:153 { -- ./candran/can-parser/parser.lua:154 -"ErrCBracketIndex", -- ./candran/can-parser/parser.lua:154 -"expected ']' to close the indexing expression" -- ./candran/can-parser/parser.lua:154 +"ErrNameIndex", -- ./candran/can-parser/parser.lua:154 +"expected a field name after '.'" -- ./candran/can-parser/parser.lua:154 }, -- ./candran/can-parser/parser.lua:154 { -- ./candran/can-parser/parser.lua:155 -"ErrNameMeth", -- ./candran/can-parser/parser.lua:155 -"expected a method name after ':'" -- ./candran/can-parser/parser.lua:155 +"ErrExprIndex", -- ./candran/can-parser/parser.lua:155 +"expected an expression after '['" -- ./candran/can-parser/parser.lua:155 }, -- ./candran/can-parser/parser.lua:155 { -- ./candran/can-parser/parser.lua:156 -"ErrMethArgs", -- ./candran/can-parser/parser.lua:156 -"expected some arguments for the method call (or '()')" -- ./candran/can-parser/parser.lua:156 +"ErrCBracketIndex", -- ./candran/can-parser/parser.lua:156 +"expected ']' to close the indexing expression" -- ./candran/can-parser/parser.lua:156 }, -- ./candran/can-parser/parser.lua:156 +{ -- ./candran/can-parser/parser.lua:157 +"ErrNameMeth", -- ./candran/can-parser/parser.lua:157 +"expected a method name after ':'" -- ./candran/can-parser/parser.lua:157 +}, -- ./candran/can-parser/parser.lua:157 { -- ./candran/can-parser/parser.lua:158 -"ErrArgList", -- ./candran/can-parser/parser.lua:158 -"expected an expression after ',' in the argument list" -- ./candran/can-parser/parser.lua:158 +"ErrMethArgs", -- ./candran/can-parser/parser.lua:158 +"expected some arguments for the method call (or '()')" -- ./candran/can-parser/parser.lua:158 }, -- ./candran/can-parser/parser.lua:158 -{ -- ./candran/can-parser/parser.lua:159 -"ErrCParenArgs", -- ./candran/can-parser/parser.lua:159 -"expected ')' to close the argument list" -- ./candran/can-parser/parser.lua:159 -}, -- ./candran/can-parser/parser.lua:159 +{ -- ./candran/can-parser/parser.lua:160 +"ErrArgList", -- ./candran/can-parser/parser.lua:160 +"expected an expression after ',' in the argument list" -- ./candran/can-parser/parser.lua:160 +}, -- ./candran/can-parser/parser.lua:160 { -- ./candran/can-parser/parser.lua:161 -"ErrCBraceTable", -- ./candran/can-parser/parser.lua:161 -"expected '}' to close the table constructor" -- ./candran/can-parser/parser.lua:161 +"ErrCParenArgs", -- ./candran/can-parser/parser.lua:161 +"expected ')' to close the argument list" -- ./candran/can-parser/parser.lua:161 }, -- ./candran/can-parser/parser.lua:161 -{ -- ./candran/can-parser/parser.lua:162 -"ErrEqField", -- ./candran/can-parser/parser.lua:162 -"expected '=' after the table key" -- ./candran/can-parser/parser.lua:162 -}, -- ./candran/can-parser/parser.lua:162 { -- ./candran/can-parser/parser.lua:163 -"ErrExprField", -- ./candran/can-parser/parser.lua:163 -"expected an expression after '='" -- ./candran/can-parser/parser.lua:163 +"ErrCBraceTable", -- ./candran/can-parser/parser.lua:163 +"expected '}' to close the table constructor" -- ./candran/can-parser/parser.lua:163 }, -- ./candran/can-parser/parser.lua:163 { -- ./candran/can-parser/parser.lua:164 -"ErrExprFKey", -- ./candran/can-parser/parser.lua:164 -"expected an expression after '[' for the table key" -- ./candran/can-parser/parser.lua:164 +"ErrEqField", -- ./candran/can-parser/parser.lua:164 +"expected '=' after the table key" -- ./candran/can-parser/parser.lua:164 }, -- ./candran/can-parser/parser.lua:164 { -- ./candran/can-parser/parser.lua:165 -"ErrCBracketFKey", -- ./candran/can-parser/parser.lua:165 -"expected ']' to close the table key" -- ./candran/can-parser/parser.lua:165 +"ErrExprField", -- ./candran/can-parser/parser.lua:165 +"expected an expression after '='" -- ./candran/can-parser/parser.lua:165 }, -- ./candran/can-parser/parser.lua:165 +{ -- ./candran/can-parser/parser.lua:166 +"ErrExprFKey", -- ./candran/can-parser/parser.lua:166 +"expected an expression after '[' for the table key" -- ./candran/can-parser/parser.lua:166 +}, -- ./candran/can-parser/parser.lua:166 { -- ./candran/can-parser/parser.lua:167 -"ErrCBraceDestructuring", -- ./candran/can-parser/parser.lua:167 -"expected '}' to close the destructuring variable list" -- ./candran/can-parser/parser.lua:167 +"ErrCBracketFKey", -- ./candran/can-parser/parser.lua:167 +"expected ']' to close the table key" -- ./candran/can-parser/parser.lua:167 }, -- ./candran/can-parser/parser.lua:167 -{ -- ./candran/can-parser/parser.lua:168 -"ErrDestructuringEqField", -- ./candran/can-parser/parser.lua:168 -"expected '=' after the table key in destructuring variable list" -- ./candran/can-parser/parser.lua:168 -}, -- ./candran/can-parser/parser.lua:168 { -- ./candran/can-parser/parser.lua:169 -"ErrDestructuringExprField", -- ./candran/can-parser/parser.lua:169 -"expected an identifier after '=' in destructuring variable list" -- ./candran/can-parser/parser.lua:169 +"ErrCBraceDestructuring", -- ./candran/can-parser/parser.lua:169 +"expected '}' to close the destructuring variable list" -- ./candran/can-parser/parser.lua:169 }, -- ./candran/can-parser/parser.lua:169 +{ -- ./candran/can-parser/parser.lua:170 +"ErrDestructuringEqField", -- ./candran/can-parser/parser.lua:170 +"expected '=' after the table key in destructuring variable list" -- ./candran/can-parser/parser.lua:170 +}, -- ./candran/can-parser/parser.lua:170 { -- ./candran/can-parser/parser.lua:171 -"ErrCBracketTableCompr", -- ./candran/can-parser/parser.lua:171 -"expected ']' to close the table comprehension" -- ./candran/can-parser/parser.lua:171 +"ErrDestructuringExprField", -- ./candran/can-parser/parser.lua:171 +"expected an identifier after '=' in destructuring variable list" -- ./candran/can-parser/parser.lua:171 }, -- ./candran/can-parser/parser.lua:171 { -- ./candran/can-parser/parser.lua:173 -"ErrDigitHex", -- ./candran/can-parser/parser.lua:173 -"expected one or more hexadecimal digits after '0x'" -- ./candran/can-parser/parser.lua:173 +"ErrCBracketTableCompr", -- ./candran/can-parser/parser.lua:173 +"expected ']' to close the table comprehension" -- ./candran/can-parser/parser.lua:173 }, -- ./candran/can-parser/parser.lua:173 -{ -- ./candran/can-parser/parser.lua:174 -"ErrDigitDeci", -- ./candran/can-parser/parser.lua:174 -"expected one or more digits after the decimal point" -- ./candran/can-parser/parser.lua:174 -}, -- ./candran/can-parser/parser.lua:174 { -- ./candran/can-parser/parser.lua:175 -"ErrDigitExpo", -- ./candran/can-parser/parser.lua:175 -"expected one or more digits for the exponent" -- ./candran/can-parser/parser.lua:175 +"ErrDigitHex", -- ./candran/can-parser/parser.lua:175 +"expected one or more hexadecimal digits after '0x'" -- ./candran/can-parser/parser.lua:175 }, -- ./candran/can-parser/parser.lua:175 +{ -- ./candran/can-parser/parser.lua:176 +"ErrDigitDeci", -- ./candran/can-parser/parser.lua:176 +"expected one or more digits after the decimal point" -- ./candran/can-parser/parser.lua:176 +}, -- ./candran/can-parser/parser.lua:176 { -- ./candran/can-parser/parser.lua:177 -"ErrQuote", -- ./candran/can-parser/parser.lua:177 -"unclosed string" -- ./candran/can-parser/parser.lua:177 +"ErrDigitExpo", -- ./candran/can-parser/parser.lua:177 +"expected one or more digits for the exponent" -- ./candran/can-parser/parser.lua:177 }, -- ./candran/can-parser/parser.lua:177 -{ -- ./candran/can-parser/parser.lua:178 -"ErrHexEsc", -- ./candran/can-parser/parser.lua:178 -"expected exactly two hexadecimal digits after '\\x'" -- ./candran/can-parser/parser.lua:178 -}, -- ./candran/can-parser/parser.lua:178 { -- ./candran/can-parser/parser.lua:179 -"ErrOBraceUEsc", -- ./candran/can-parser/parser.lua:179 -"expected '{' after '\\u'" -- ./candran/can-parser/parser.lua:179 +"ErrQuote", -- ./candran/can-parser/parser.lua:179 +"unclosed string" -- ./candran/can-parser/parser.lua:179 }, -- ./candran/can-parser/parser.lua:179 { -- ./candran/can-parser/parser.lua:180 -"ErrDigitUEsc", -- ./candran/can-parser/parser.lua:180 -"expected one or more hexadecimal digits for the UTF-8 code point" -- ./candran/can-parser/parser.lua:180 +"ErrHexEsc", -- ./candran/can-parser/parser.lua:180 +"expected exactly two hexadecimal digits after '\\x'" -- ./candran/can-parser/parser.lua:180 }, -- ./candran/can-parser/parser.lua:180 { -- ./candran/can-parser/parser.lua:181 -"ErrCBraceUEsc", -- ./candran/can-parser/parser.lua:181 -"expected '}' after the code point" -- ./candran/can-parser/parser.lua:181 +"ErrOBraceUEsc", -- ./candran/can-parser/parser.lua:181 +"expected '{' after '\\u'" -- ./candran/can-parser/parser.lua:181 }, -- ./candran/can-parser/parser.lua:181 { -- ./candran/can-parser/parser.lua:182 -"ErrEscSeq", -- ./candran/can-parser/parser.lua:182 -"invalid escape sequence" -- ./candran/can-parser/parser.lua:182 +"ErrDigitUEsc", -- ./candran/can-parser/parser.lua:182 +"expected one or more hexadecimal digits for the UTF-8 code point" -- ./candran/can-parser/parser.lua:182 }, -- ./candran/can-parser/parser.lua:182 { -- ./candran/can-parser/parser.lua:183 -"ErrCloseLStr", -- ./candran/can-parser/parser.lua:183 -"unclosed long string" -- ./candran/can-parser/parser.lua:183 -} -- ./candran/can-parser/parser.lua:183 -} -- ./candran/can-parser/parser.lua:183 -local function throw(label) -- ./candran/can-parser/parser.lua:186 -label = "Err" .. label -- ./candran/can-parser/parser.lua:187 -for i, labelinfo in ipairs(labels) do -- ./candran/can-parser/parser.lua:188 -if labelinfo[1] == label then -- ./candran/can-parser/parser.lua:189 -return T(i) -- ./candran/can-parser/parser.lua:190 -end -- ./candran/can-parser/parser.lua:190 -end -- ./candran/can-parser/parser.lua:190 -error("Label not found: " .. label) -- ./candran/can-parser/parser.lua:194 -end -- ./candran/can-parser/parser.lua:194 -local function expect(patt, label) -- ./candran/can-parser/parser.lua:197 -return patt + throw(label) -- ./candran/can-parser/parser.lua:198 -end -- ./candran/can-parser/parser.lua:198 -local function token(patt) -- ./candran/can-parser/parser.lua:204 -return patt * V("Skip") -- ./candran/can-parser/parser.lua:205 -end -- ./candran/can-parser/parser.lua:205 -local function sym(str) -- ./candran/can-parser/parser.lua:208 -return token(P(str)) -- ./candran/can-parser/parser.lua:209 -end -- ./candran/can-parser/parser.lua:209 -local function kw(str) -- ./candran/can-parser/parser.lua:212 -return token(P(str) * - V("IdRest")) -- ./candran/can-parser/parser.lua:213 -end -- ./candran/can-parser/parser.lua:213 -local function tagC(tag, patt) -- ./candran/can-parser/parser.lua:216 -return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./candran/can-parser/parser.lua:217 -end -- ./candran/can-parser/parser.lua:217 -local function unaryOp(op, e) -- ./candran/can-parser/parser.lua:220 -return { -- ./candran/can-parser/parser.lua:221 -["tag"] = "Op", -- ./candran/can-parser/parser.lua:221 -["pos"] = e["pos"], -- ./candran/can-parser/parser.lua:221 -[1] = op, -- ./candran/can-parser/parser.lua:221 -[2] = e -- ./candran/can-parser/parser.lua:221 -} -- ./candran/can-parser/parser.lua:221 -end -- ./candran/can-parser/parser.lua:221 -local function binaryOp(e1, op, e2) -- ./candran/can-parser/parser.lua:224 -if not op then -- ./candran/can-parser/parser.lua:225 -return e1 -- ./candran/can-parser/parser.lua:226 -else -- ./candran/can-parser/parser.lua:226 -return { -- ./candran/can-parser/parser.lua:228 -["tag"] = "Op", -- ./candran/can-parser/parser.lua:228 -["pos"] = e1["pos"], -- ./candran/can-parser/parser.lua:228 -[1] = op, -- ./candran/can-parser/parser.lua:228 -[2] = e1, -- ./candran/can-parser/parser.lua:228 -[3] = e2 -- ./candran/can-parser/parser.lua:228 -} -- ./candran/can-parser/parser.lua:228 -end -- ./candran/can-parser/parser.lua:228 -end -- ./candran/can-parser/parser.lua:228 -local function sepBy(patt, sep, label) -- ./candran/can-parser/parser.lua:232 -if label then -- ./candran/can-parser/parser.lua:233 -return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./candran/can-parser/parser.lua:234 -else -- ./candran/can-parser/parser.lua:234 -return patt * Cg(sep * patt) ^ 0 -- ./candran/can-parser/parser.lua:236 -end -- ./candran/can-parser/parser.lua:236 -end -- ./candran/can-parser/parser.lua:236 -local function chainOp(patt, sep, label) -- ./candran/can-parser/parser.lua:240 -return Cf(sepBy(patt, sep, label), binaryOp) -- ./candran/can-parser/parser.lua:241 +"ErrCBraceUEsc", -- ./candran/can-parser/parser.lua:183 +"expected '}' after the code point" -- ./candran/can-parser/parser.lua:183 +}, -- ./candran/can-parser/parser.lua:183 +{ -- ./candran/can-parser/parser.lua:184 +"ErrEscSeq", -- ./candran/can-parser/parser.lua:184 +"invalid escape sequence" -- ./candran/can-parser/parser.lua:184 +}, -- ./candran/can-parser/parser.lua:184 +{ -- ./candran/can-parser/parser.lua:185 +"ErrCloseLStr", -- ./candran/can-parser/parser.lua:185 +"unclosed long string" -- ./candran/can-parser/parser.lua:185 +}, -- ./candran/can-parser/parser.lua:185 +{ -- ./candran/can-parser/parser.lua:187 +"ErrUnknownAttribute", -- ./candran/can-parser/parser.lua:187 +"unknown variable attribute" -- ./candran/can-parser/parser.lua:187 +}, -- ./candran/can-parser/parser.lua:187 +{ -- ./candran/can-parser/parser.lua:188 +"ErrCBracketAttribute", -- ./candran/can-parser/parser.lua:188 +"expected '>' to close the variable attribute" -- ./candran/can-parser/parser.lua:188 +} -- ./candran/can-parser/parser.lua:188 +} -- ./candran/can-parser/parser.lua:188 +local function throw(label) -- ./candran/can-parser/parser.lua:191 +label = "Err" .. label -- ./candran/can-parser/parser.lua:192 +for i, labelinfo in ipairs(labels) do -- ./candran/can-parser/parser.lua:193 +if labelinfo[1] == label then -- ./candran/can-parser/parser.lua:194 +return T(i) -- ./candran/can-parser/parser.lua:195 +end -- ./candran/can-parser/parser.lua:195 +end -- ./candran/can-parser/parser.lua:195 +error("Label not found: " .. label) -- ./candran/can-parser/parser.lua:199 +end -- ./candran/can-parser/parser.lua:199 +local function expect(patt, label) -- ./candran/can-parser/parser.lua:202 +return patt + throw(label) -- ./candran/can-parser/parser.lua:203 +end -- ./candran/can-parser/parser.lua:203 +local function token(patt) -- ./candran/can-parser/parser.lua:209 +return patt * V("Skip") -- ./candran/can-parser/parser.lua:210 +end -- ./candran/can-parser/parser.lua:210 +local function sym(str) -- ./candran/can-parser/parser.lua:213 +return token(P(str)) -- ./candran/can-parser/parser.lua:214 +end -- ./candran/can-parser/parser.lua:214 +local function kw(str) -- ./candran/can-parser/parser.lua:217 +return token(P(str) * - V("IdRest")) -- ./candran/can-parser/parser.lua:218 +end -- ./candran/can-parser/parser.lua:218 +local function tagC(tag, patt) -- ./candran/can-parser/parser.lua:221 +return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt) -- ./candran/can-parser/parser.lua:222 +end -- ./candran/can-parser/parser.lua:222 +local function unaryOp(op, e) -- ./candran/can-parser/parser.lua:225 +return { -- ./candran/can-parser/parser.lua:226 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:226 +["pos"] = e["pos"], -- ./candran/can-parser/parser.lua:226 +[1] = op, -- ./candran/can-parser/parser.lua:226 +[2] = e -- ./candran/can-parser/parser.lua:226 +} -- ./candran/can-parser/parser.lua:226 +end -- ./candran/can-parser/parser.lua:226 +local function binaryOp(e1, op, e2) -- ./candran/can-parser/parser.lua:229 +if not op then -- ./candran/can-parser/parser.lua:230 +return e1 -- ./candran/can-parser/parser.lua:231 +else -- ./candran/can-parser/parser.lua:231 +return { -- ./candran/can-parser/parser.lua:233 +["tag"] = "Op", -- ./candran/can-parser/parser.lua:233 +["pos"] = e1["pos"], -- ./candran/can-parser/parser.lua:233 +[1] = op, -- ./candran/can-parser/parser.lua:233 +[2] = e1, -- ./candran/can-parser/parser.lua:233 +[3] = e2 -- ./candran/can-parser/parser.lua:233 +} -- ./candran/can-parser/parser.lua:233 +end -- ./candran/can-parser/parser.lua:233 +end -- ./candran/can-parser/parser.lua:233 +local function sepBy(patt, sep, label) -- ./candran/can-parser/parser.lua:237 +if label then -- ./candran/can-parser/parser.lua:238 +return patt * Cg(sep * expect(patt, label)) ^ 0 -- ./candran/can-parser/parser.lua:239 +else -- ./candran/can-parser/parser.lua:239 +return patt * Cg(sep * patt) ^ 0 -- ./candran/can-parser/parser.lua:241 end -- ./candran/can-parser/parser.lua:241 -local function commaSep(patt, label) -- ./candran/can-parser/parser.lua:244 -return sepBy(patt, sym(","), label) -- ./candran/can-parser/parser.lua:245 -end -- ./candran/can-parser/parser.lua:245 -local function tagDo(block) -- ./candran/can-parser/parser.lua:248 -block["tag"] = "Do" -- ./candran/can-parser/parser.lua:249 -return block -- ./candran/can-parser/parser.lua:250 +end -- ./candran/can-parser/parser.lua:241 +local function chainOp(patt, sep, label) -- ./candran/can-parser/parser.lua:245 +return Cf(sepBy(patt, sep, label), binaryOp) -- ./candran/can-parser/parser.lua:246 +end -- ./candran/can-parser/parser.lua:246 +local function commaSep(patt, label) -- ./candran/can-parser/parser.lua:249 +return sepBy(patt, sym(","), label) -- ./candran/can-parser/parser.lua:250 end -- ./candran/can-parser/parser.lua:250 -local function fixFuncStat(func) -- ./candran/can-parser/parser.lua:253 -if func[1]["is_method"] then -- ./candran/can-parser/parser.lua:254 -table["insert"](func[2][1], 1, { -- ./candran/can-parser/parser.lua:254 -["tag"] = "Id", -- ./candran/can-parser/parser.lua:254 -[1] = "self" -- ./candran/can-parser/parser.lua:254 -}) -- ./candran/can-parser/parser.lua:254 -end -- ./candran/can-parser/parser.lua:254 -func[1] = { func[1] } -- ./candran/can-parser/parser.lua:255 -func[2] = { func[2] } -- ./candran/can-parser/parser.lua:256 -return func -- ./candran/can-parser/parser.lua:257 -end -- ./candran/can-parser/parser.lua:257 -local function addDots(params, dots) -- ./candran/can-parser/parser.lua:260 -if dots then -- ./candran/can-parser/parser.lua:261 -table["insert"](params, dots) -- ./candran/can-parser/parser.lua:261 -end -- ./candran/can-parser/parser.lua:261 -return params -- ./candran/can-parser/parser.lua:262 +local function tagDo(block) -- ./candran/can-parser/parser.lua:253 +block["tag"] = "Do" -- ./candran/can-parser/parser.lua:254 +return block -- ./candran/can-parser/parser.lua:255 +end -- ./candran/can-parser/parser.lua:255 +local function fixFuncStat(func) -- ./candran/can-parser/parser.lua:258 +if func[1]["is_method"] then -- ./candran/can-parser/parser.lua:259 +table["insert"](func[2][1], 1, { -- ./candran/can-parser/parser.lua:259 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:259 +[1] = "self" -- ./candran/can-parser/parser.lua:259 +}) -- ./candran/can-parser/parser.lua:259 +end -- ./candran/can-parser/parser.lua:259 +func[1] = { func[1] } -- ./candran/can-parser/parser.lua:260 +func[2] = { func[2] } -- ./candran/can-parser/parser.lua:261 +return func -- ./candran/can-parser/parser.lua:262 end -- ./candran/can-parser/parser.lua:262 -local function insertIndex(t, index) -- ./candran/can-parser/parser.lua:265 -return { -- ./candran/can-parser/parser.lua:266 -["tag"] = "Index", -- ./candran/can-parser/parser.lua:266 -["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:266 -[1] = t, -- ./candran/can-parser/parser.lua:266 -[2] = index -- ./candran/can-parser/parser.lua:266 -} -- ./candran/can-parser/parser.lua:266 +local function addDots(params, dots) -- ./candran/can-parser/parser.lua:265 +if dots then -- ./candran/can-parser/parser.lua:266 +table["insert"](params, dots) -- ./candran/can-parser/parser.lua:266 end -- ./candran/can-parser/parser.lua:266 -local function markMethod(t, method) -- ./candran/can-parser/parser.lua:269 -if method then -- ./candran/can-parser/parser.lua:270 +return params -- ./candran/can-parser/parser.lua:267 +end -- ./candran/can-parser/parser.lua:267 +local function insertIndex(t, index) -- ./candran/can-parser/parser.lua:270 return { -- ./candran/can-parser/parser.lua:271 ["tag"] = "Index", -- ./candran/can-parser/parser.lua:271 ["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:271 -["is_method"] = true, -- ./candran/can-parser/parser.lua:271 [1] = t, -- ./candran/can-parser/parser.lua:271 -[2] = method -- ./candran/can-parser/parser.lua:271 +[2] = index -- ./candran/can-parser/parser.lua:271 } -- ./candran/can-parser/parser.lua:271 end -- ./candran/can-parser/parser.lua:271 -return t -- ./candran/can-parser/parser.lua:273 -end -- ./candran/can-parser/parser.lua:273 -local function makeSuffixedExpr(t1, t2) -- ./candran/can-parser/parser.lua:276 -if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./candran/can-parser/parser.lua:277 -local t = { -- ./candran/can-parser/parser.lua:278 -["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:278 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:278 -[1] = t1 -- ./candran/can-parser/parser.lua:278 -} -- ./candran/can-parser/parser.lua:278 -for k, v in ipairs(t2) do -- ./candran/can-parser/parser.lua:279 -table["insert"](t, v) -- ./candran/can-parser/parser.lua:280 -end -- ./candran/can-parser/parser.lua:280 -return t -- ./candran/can-parser/parser.lua:282 -elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./candran/can-parser/parser.lua:283 -return { -- ./candran/can-parser/parser.lua:284 -["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:284 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:284 -[1] = t1, -- ./candran/can-parser/parser.lua:284 -[2] = t2[1] -- ./candran/can-parser/parser.lua:284 -} -- ./candran/can-parser/parser.lua:284 -elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./candran/can-parser/parser.lua:285 -return { -- ./candran/can-parser/parser.lua:286 -["tag"] = "SafeIndex", -- ./candran/can-parser/parser.lua:286 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:286 -[1] = t1, -- ./candran/can-parser/parser.lua:286 -[2] = t2[1] -- ./candran/can-parser/parser.lua:286 -} -- ./candran/can-parser/parser.lua:286 -elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./candran/can-parser/parser.lua:287 -return { -- ./candran/can-parser/parser.lua:288 -["tag"] = "Index", -- ./candran/can-parser/parser.lua:288 -["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:288 -[1] = t1, -- ./candran/can-parser/parser.lua:288 -[2] = t2[1] -- ./candran/can-parser/parser.lua:288 -} -- ./candran/can-parser/parser.lua:288 -else -- ./candran/can-parser/parser.lua:288 -error("unexpected tag in suffixed expression") -- ./candran/can-parser/parser.lua:290 -end -- ./candran/can-parser/parser.lua:290 -end -- ./candran/can-parser/parser.lua:290 -local function fixShortFunc(t) -- ./candran/can-parser/parser.lua:294 -if t[1] == ":" then -- ./candran/can-parser/parser.lua:295 -table["insert"](t[2], 1, { -- ./candran/can-parser/parser.lua:296 -["tag"] = "Id", -- ./candran/can-parser/parser.lua:296 -"self" -- ./candran/can-parser/parser.lua:296 -}) -- ./candran/can-parser/parser.lua:296 -table["remove"](t, 1) -- ./candran/can-parser/parser.lua:297 -t["is_method"] = true -- ./candran/can-parser/parser.lua:298 -end -- ./candran/can-parser/parser.lua:298 -t["is_short"] = true -- ./candran/can-parser/parser.lua:300 -return t -- ./candran/can-parser/parser.lua:301 -end -- ./candran/can-parser/parser.lua:301 -local function statToExpr(t) -- ./candran/can-parser/parser.lua:304 -t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:305 +local function markMethod(t, method) -- ./candran/can-parser/parser.lua:274 +if method then -- ./candran/can-parser/parser.lua:275 +return { -- ./candran/can-parser/parser.lua:276 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:276 +["pos"] = t["pos"], -- ./candran/can-parser/parser.lua:276 +["is_method"] = true, -- ./candran/can-parser/parser.lua:276 +[1] = t, -- ./candran/can-parser/parser.lua:276 +[2] = method -- ./candran/can-parser/parser.lua:276 +} -- ./candran/can-parser/parser.lua:276 +end -- ./candran/can-parser/parser.lua:276 +return t -- ./candran/can-parser/parser.lua:278 +end -- ./candran/can-parser/parser.lua:278 +local function makeSuffixedExpr(t1, t2) -- ./candran/can-parser/parser.lua:281 +if t2["tag"] == "Call" or t2["tag"] == "SafeCall" then -- ./candran/can-parser/parser.lua:282 +local t = { -- ./candran/can-parser/parser.lua:283 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:283 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:283 +[1] = t1 -- ./candran/can-parser/parser.lua:283 +} -- ./candran/can-parser/parser.lua:283 +for k, v in ipairs(t2) do -- ./candran/can-parser/parser.lua:284 +table["insert"](t, v) -- ./candran/can-parser/parser.lua:285 +end -- ./candran/can-parser/parser.lua:285 +return t -- ./candran/can-parser/parser.lua:287 +elseif t2["tag"] == "MethodStub" or t2["tag"] == "SafeMethodStub" then -- ./candran/can-parser/parser.lua:288 +return { -- ./candran/can-parser/parser.lua:289 +["tag"] = t2["tag"], -- ./candran/can-parser/parser.lua:289 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:289 +[1] = t1, -- ./candran/can-parser/parser.lua:289 +[2] = t2[1] -- ./candran/can-parser/parser.lua:289 +} -- ./candran/can-parser/parser.lua:289 +elseif t2["tag"] == "SafeDotIndex" or t2["tag"] == "SafeArrayIndex" then -- ./candran/can-parser/parser.lua:290 +return { -- ./candran/can-parser/parser.lua:291 +["tag"] = "SafeIndex", -- ./candran/can-parser/parser.lua:291 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:291 +[1] = t1, -- ./candran/can-parser/parser.lua:291 +[2] = t2[1] -- ./candran/can-parser/parser.lua:291 +} -- ./candran/can-parser/parser.lua:291 +elseif t2["tag"] == "DotIndex" or t2["tag"] == "ArrayIndex" then -- ./candran/can-parser/parser.lua:292 +return { -- ./candran/can-parser/parser.lua:293 +["tag"] = "Index", -- ./candran/can-parser/parser.lua:293 +["pos"] = t1["pos"], -- ./candran/can-parser/parser.lua:293 +[1] = t1, -- ./candran/can-parser/parser.lua:293 +[2] = t2[1] -- ./candran/can-parser/parser.lua:293 +} -- ./candran/can-parser/parser.lua:293 +else -- ./candran/can-parser/parser.lua:293 +error("unexpected tag in suffixed expression") -- ./candran/can-parser/parser.lua:295 +end -- ./candran/can-parser/parser.lua:295 +end -- ./candran/can-parser/parser.lua:295 +local function fixShortFunc(t) -- ./candran/can-parser/parser.lua:299 +if t[1] == ":" then -- ./candran/can-parser/parser.lua:300 +table["insert"](t[2], 1, { -- ./candran/can-parser/parser.lua:301 +["tag"] = "Id", -- ./candran/can-parser/parser.lua:301 +"self" -- ./candran/can-parser/parser.lua:301 +}) -- ./candran/can-parser/parser.lua:301 +table["remove"](t, 1) -- ./candran/can-parser/parser.lua:302 +t["is_method"] = true -- ./candran/can-parser/parser.lua:303 +end -- ./candran/can-parser/parser.lua:303 +t["is_short"] = true -- ./candran/can-parser/parser.lua:305 return t -- ./candran/can-parser/parser.lua:306 end -- ./candran/can-parser/parser.lua:306 -local function fixStructure(t) -- ./candran/can-parser/parser.lua:309 -local i = 1 -- ./candran/can-parser/parser.lua:310 -while i <= # t do -- ./candran/can-parser/parser.lua:311 -if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:312 -fixStructure(t[i]) -- ./candran/can-parser/parser.lua:313 -for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:314 -local stat = t[i][j] -- ./candran/can-parser/parser.lua:315 -if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:316 -table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:317 -table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:318 -if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:319 -stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:320 -end -- ./candran/can-parser/parser.lua:320 -end -- ./candran/can-parser/parser.lua:320 -end -- ./candran/can-parser/parser.lua:320 -end -- ./candran/can-parser/parser.lua:320 -i = i + 1 -- ./candran/can-parser/parser.lua:325 +local function statToExpr(t) -- ./candran/can-parser/parser.lua:309 +t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:310 +return t -- ./candran/can-parser/parser.lua:311 +end -- ./candran/can-parser/parser.lua:311 +local function fixStructure(t) -- ./candran/can-parser/parser.lua:314 +local i = 1 -- ./candran/can-parser/parser.lua:315 +while i <= # t do -- ./candran/can-parser/parser.lua:316 +if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:317 +fixStructure(t[i]) -- ./candran/can-parser/parser.lua:318 +for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:319 +local stat = t[i][j] -- ./candran/can-parser/parser.lua:320 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:321 +table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:322 +table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:323 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:324 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:325 end -- ./candran/can-parser/parser.lua:325 -return t -- ./candran/can-parser/parser.lua:327 -end -- ./candran/can-parser/parser.lua:327 -local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:330 -for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:331 -if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:333 -local exprlist -- ./candran/can-parser/parser.lua:334 -if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:336 -exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:337 -elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:338 -exprlist = stat -- ./candran/can-parser/parser.lua:339 -end -- ./candran/can-parser/parser.lua:339 -local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:342 -if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:346 -local p = i -- ./candran/can-parser/parser.lua:347 -for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:348 -p = i + j -- ./candran/can-parser/parser.lua:349 -table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:350 -if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:352 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:353 -end -- ./candran/can-parser/parser.lua:353 -if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:356 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:357 -end -- ./candran/can-parser/parser.lua:357 -end -- ./candran/can-parser/parser.lua:357 -exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:361 -exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:362 -if not isRecCall then -- ./candran/can-parser/parser.lua:364 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:365 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:366 -end -- ./candran/can-parser/parser.lua:366 -end -- ./candran/can-parser/parser.lua:366 -return block, i -- ./candran/can-parser/parser.lua:370 -elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:373 -local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:374 -if r then -- ./candran/can-parser/parser.lua:375 -for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:376 -table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:377 -end -- ./candran/can-parser/parser.lua:377 -return block, i -- ./candran/can-parser/parser.lua:379 -end -- ./candran/can-parser/parser.lua:379 -elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:381 -local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:382 -if r then -- ./candran/can-parser/parser.lua:383 +end -- ./candran/can-parser/parser.lua:325 +end -- ./candran/can-parser/parser.lua:325 +end -- ./candran/can-parser/parser.lua:325 +i = i + 1 -- ./candran/can-parser/parser.lua:330 +end -- ./candran/can-parser/parser.lua:330 +return t -- ./candran/can-parser/parser.lua:332 +end -- ./candran/can-parser/parser.lua:332 +local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:335 +for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:336 +if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:338 +local exprlist -- ./candran/can-parser/parser.lua:339 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:341 +exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:342 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:343 +exprlist = stat -- ./candran/can-parser/parser.lua:344 +end -- ./candran/can-parser/parser.lua:344 +local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:347 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:351 +local p = i -- ./candran/can-parser/parser.lua:352 +for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:353 +p = i + j -- ./candran/can-parser/parser.lua:354 +table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:355 +if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:357 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:358 +end -- ./candran/can-parser/parser.lua:358 +if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:361 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:362 +end -- ./candran/can-parser/parser.lua:362 +end -- ./candran/can-parser/parser.lua:362 +exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:366 +exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:367 +if not isRecCall then -- ./candran/can-parser/parser.lua:369 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:370 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:371 +end -- ./candran/can-parser/parser.lua:371 +end -- ./candran/can-parser/parser.lua:371 +return block, i -- ./candran/can-parser/parser.lua:375 +elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:378 +local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:379 +if r then -- ./candran/can-parser/parser.lua:380 +for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:381 +table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:382 +end -- ./candran/can-parser/parser.lua:382 return block, i -- ./candran/can-parser/parser.lua:384 end -- ./candran/can-parser/parser.lua:384 -end -- ./candran/can-parser/parser.lua:384 -elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:389 -local blocks -- ./candran/can-parser/parser.lua:390 -if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:392 -blocks = stat -- ./candran/can-parser/parser.lua:393 -elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:394 -blocks = { stat } -- ./candran/can-parser/parser.lua:395 -end -- ./candran/can-parser/parser.lua:395 -for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:398 -if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:399 -local oldLen = # iblock -- ./candran/can-parser/parser.lua:400 -local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:401 -if newiBlock then -- ./candran/can-parser/parser.lua:402 -local p = i -- ./candran/can-parser/parser.lua:403 -for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:404 -p = p + 1 -- ./candran/can-parser/parser.lua:405 -table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:406 -iblock[j] = nil -- ./candran/can-parser/parser.lua:407 -end -- ./candran/can-parser/parser.lua:407 -if not isRecCall then -- ./candran/can-parser/parser.lua:410 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:411 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:412 +elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:386 +local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:387 +if r then -- ./candran/can-parser/parser.lua:388 +return block, i -- ./candran/can-parser/parser.lua:389 +end -- ./candran/can-parser/parser.lua:389 +end -- ./candran/can-parser/parser.lua:389 +elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:394 +local blocks -- ./candran/can-parser/parser.lua:395 +if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:397 +blocks = stat -- ./candran/can-parser/parser.lua:398 +elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:399 +blocks = { stat } -- ./candran/can-parser/parser.lua:400 +end -- ./candran/can-parser/parser.lua:400 +for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:403 +if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:404 +local oldLen = # iblock -- ./candran/can-parser/parser.lua:405 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:406 +if newiBlock then -- ./candran/can-parser/parser.lua:407 +local p = i -- ./candran/can-parser/parser.lua:408 +for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:409 +p = p + 1 -- ./candran/can-parser/parser.lua:410 +table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:411 +iblock[j] = nil -- ./candran/can-parser/parser.lua:412 end -- ./candran/can-parser/parser.lua:412 -end -- ./candran/can-parser/parser.lua:412 -return block, i -- ./candran/can-parser/parser.lua:416 -end -- ./candran/can-parser/parser.lua:416 -end -- ./candran/can-parser/parser.lua:416 -end -- ./candran/can-parser/parser.lua:416 -end -- ./candran/can-parser/parser.lua:416 -end -- ./candran/can-parser/parser.lua:416 -return nil -- ./candran/can-parser/parser.lua:422 -end -- ./candran/can-parser/parser.lua:422 -local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:425 -local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:426 -if not r then -- ./candran/can-parser/parser.lua:427 -return false -- ./candran/can-parser/parser.lua:428 -end -- ./candran/can-parser/parser.lua:428 -return true, r -- ./candran/can-parser/parser.lua:430 -end -- ./candran/can-parser/parser.lua:430 -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:433 -if canFollow then -- ./candran/can-parser/parser.lua:434 -return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:437 -else -- ./candran/can-parser/parser.lua:437 -return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:441 -end -- ./candran/can-parser/parser.lua:441 -end -- ./candran/can-parser/parser.lua:441 -local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:445 -return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:447 -end -- ./candran/can-parser/parser.lua:447 -local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:450 -return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:452 +if not isRecCall then -- ./candran/can-parser/parser.lua:415 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:416 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:417 +end -- ./candran/can-parser/parser.lua:417 +end -- ./candran/can-parser/parser.lua:417 +return block, i -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +end -- ./candran/can-parser/parser.lua:421 +return nil -- ./candran/can-parser/parser.lua:427 +end -- ./candran/can-parser/parser.lua:427 +local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:430 +local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:431 +if not r then -- ./candran/can-parser/parser.lua:432 +return false -- ./candran/can-parser/parser.lua:433 +end -- ./candran/can-parser/parser.lua:433 +return true, r -- ./candran/can-parser/parser.lua:435 +end -- ./candran/can-parser/parser.lua:435 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:438 +if canFollow then -- ./candran/can-parser/parser.lua:439 +return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:442 +else -- ./candran/can-parser/parser.lua:442 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:446 +end -- ./candran/can-parser/parser.lua:446 +end -- ./candran/can-parser/parser.lua:446 +local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:450 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:452 end -- ./candran/can-parser/parser.lua:452 -local function maybe(patt) -- ./candran/can-parser/parser.lua:455 -return # patt / 0 * patt -- ./candran/can-parser/parser.lua:456 -end -- ./candran/can-parser/parser.lua:456 -local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:460 -local function push(f) -- ./candran/can-parser/parser.lua:462 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:463 -table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:464 -return true -- ./candran/can-parser/parser.lua:465 -end) -- ./candran/can-parser/parser.lua:465 -end -- ./candran/can-parser/parser.lua:465 -local function pop(f) -- ./candran/can-parser/parser.lua:468 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:469 -table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:470 -return true -- ./candran/can-parser/parser.lua:471 -end) -- ./candran/can-parser/parser.lua:471 -end -- ./candran/can-parser/parser.lua:471 -local function when(f) -- ./candran/can-parser/parser.lua:474 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:475 -return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:476 -end) -- ./candran/can-parser/parser.lua:476 -end -- ./candran/can-parser/parser.lua:476 -local function set(f, patt) -- ./candran/can-parser/parser.lua:479 -return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:480 -end -- ./candran/can-parser/parser.lua:480 -local G = { -- ./candran/can-parser/parser.lua:484 -V("Lua"), -- ./candran/can-parser/parser.lua:484 -["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:485 +local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:455 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:457 +end -- ./candran/can-parser/parser.lua:457 +local function maybe(patt) -- ./candran/can-parser/parser.lua:460 +return # patt / 0 * patt -- ./candran/can-parser/parser.lua:461 +end -- ./candran/can-parser/parser.lua:461 +local function setAttribute(attribute) -- ./candran/can-parser/parser.lua:464 +return function(assign) -- ./candran/can-parser/parser.lua:465 +assign[1]["tag"] = "AttributeNameList" -- ./candran/can-parser/parser.lua:466 +for _, id in ipairs(assign[1]) do -- ./candran/can-parser/parser.lua:467 +if id["tag"] == "Id" then -- ./candran/can-parser/parser.lua:468 +id["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:469 +id[2] = attribute -- ./candran/can-parser/parser.lua:470 +elseif id["tag"] == "DestructuringId" then -- ./candran/can-parser/parser.lua:471 +for _, did in ipairs(id) do -- ./candran/can-parser/parser.lua:472 +did["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:473 +did[2] = attribute -- ./candran/can-parser/parser.lua:474 +end -- ./candran/can-parser/parser.lua:474 +end -- ./candran/can-parser/parser.lua:474 +end -- ./candran/can-parser/parser.lua:474 +return assign -- ./candran/can-parser/parser.lua:478 +end -- ./candran/can-parser/parser.lua:478 +end -- ./candran/can-parser/parser.lua:478 +local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:483 +local function push(f) -- ./candran/can-parser/parser.lua:485 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:486 +table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:487 +return true -- ./candran/can-parser/parser.lua:488 +end) -- ./candran/can-parser/parser.lua:488 +end -- ./candran/can-parser/parser.lua:488 +local function pop(f) -- ./candran/can-parser/parser.lua:491 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:492 +table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:493 +return true -- ./candran/can-parser/parser.lua:494 +end) -- ./candran/can-parser/parser.lua:494 +end -- ./candran/can-parser/parser.lua:494 +local function when(f) -- ./candran/can-parser/parser.lua:497 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:498 +return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:499 +end) -- ./candran/can-parser/parser.lua:499 +end -- ./candran/can-parser/parser.lua:499 +local function set(f, patt) -- ./candran/can-parser/parser.lua:502 +return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:503 +end -- ./candran/can-parser/parser.lua:503 +local G = { -- ./candran/can-parser/parser.lua:507 +V("Lua"), -- ./candran/can-parser/parser.lua:507 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:508 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:486 -["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:488 -["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:494 -["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:495 -["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:497 -t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:497 -return t -- ./candran/can-parser/parser.lua:497 -end, -- ./candran/can-parser/parser.lua:497 -["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:498 -["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:500 -["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:501 -["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:502 -["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:503 -["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:505 -["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:506 -["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:507 -["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:508 -["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:510 -["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:511 -["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:513 -["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:514 -["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:515 -["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:517 -["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:518 -["LocalAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:520 -["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:522 -["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:524 -["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:526 -["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:528 -["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:530 -["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:531 -["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:532 -["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:535 -["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:537 -["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:538 -["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:540 -["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:542 -["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:543 -["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:545 -["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:546 -["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:547 -["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:548 -["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:549 -["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:551 -["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./candran/can-parser/parser.lua:552 -["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:554 -["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:555 -["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:556 -["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:557 -["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:559 -["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:560 -["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:562 -["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:564 -["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:565 -["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:566 -["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:567 -["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:568 -["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:569 -["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:570 -["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:571 -["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:572 -["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:573 -["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:574 -["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:576 -["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:577 -["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:587 -["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:589 -["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:591 -return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:591 -end), -- ./candran/can-parser/parser.lua:591 -["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:592 -return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:592 -end), -- ./candran/can-parser/parser.lua:592 -["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:596 -["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:599 -["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:600 -["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:604 -["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:606 -["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:608 -["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:609 -["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:610 -["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:612 -["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:615 -["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:617 -["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:618 -["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:620 -["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:622 -["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:623 -["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:625 -["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:627 -["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:628 -["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:629 -["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:632 -["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:633 -["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:634 -return -- ./candran/can-parser/parser.lua:634 +")) ^ 0, -- ./candran/can-parser/parser.lua:509 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:511 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("ConstStat") + V("CloseStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:517 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:518 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:520 +t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:520 +return t -- ./candran/can-parser/parser.lua:520 +end, -- ./candran/can-parser/parser.lua:520 +["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:521 +["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:523 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:524 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:525 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:526 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:528 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:529 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:530 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:531 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:533 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:534 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:536 +["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:537 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:538 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:540 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:541 +["LocalAssign"] = tagC("Local", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:543 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:545 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:547 +["ConstStat"] = kw("const") * expect(V("AttributeAssign") / setAttribute("const"), "DefConst"), -- ./candran/can-parser/parser.lua:549 +["CloseStat"] = kw("close") * expect(V("AttributeAssign") / setAttribute("close"), "DefClose"), -- ./candran/can-parser/parser.lua:550 +["AttributeAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:552 +["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:554 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:556 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:558 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:559 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:560 +["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:563 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:565 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:566 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:568 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:570 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:571 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:573 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:574 +["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:575 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:576 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:577 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:579 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./candran/can-parser/parser.lua:580 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:582 +["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:583 +["AttributeNameList"] = tagC("AttributeNameList", commaSep(V("AttributeId"))), -- ./candran/can-parser/parser.lua:584 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:585 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:586 +["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:588 +["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:589 +["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:591 +["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:593 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:594 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:595 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:596 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:597 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:598 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:599 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:600 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:601 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:602 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:603 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:605 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:606 +["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:616 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:618 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:620 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:620 +end), -- ./candran/can-parser/parser.lua:620 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:621 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:621 +end), -- ./candran/can-parser/parser.lua:621 +["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:625 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:628 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:629 +["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:633 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:635 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:637 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:638 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:639 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:641 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:644 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:646 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:647 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:649 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:651 +["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:652 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:654 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:656 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:657 +["AttributeSelfId"] = tagC("AttributeId", sym("@") / "self" * V("Attribute") ^ - 1), -- ./candran/can-parser/parser.lua:658 +["AttributeId"] = tagC("AttributeId", V("Name") * V("Attribute") ^ - 1) + V("AttributeSelfId"), -- ./candran/can-parser/parser.lua:659 +["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:660 +["Attribute"] = sym("<") * expect(kw("const") / "const" + kw("close") / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"), -- ./candran/can-parser/parser.lua:662 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:665 +["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:666 +["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:667 +return -- ./candran/can-parser/parser.lua:667 end + P("--") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:635 -["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:637 -["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:638 -["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:642 -["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:643 -["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:644 -["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:645 -["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:647 -["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:648 -["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:650 -["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:652 -["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:653 -["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:654 -["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:655 -["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:656 -["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:658 +")) ^ 0, -- ./candran/can-parser/parser.lua:668 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:670 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:671 +["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:675 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:676 +["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:677 +["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:678 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:680 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:681 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:683 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:685 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:686 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:687 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:688 +["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:689 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:691 ["ShortStr"] = P("\"") * Cs((V("EscSeq") + (P(1) - S("\"\ "))) ^ 0) * expect(P("\""), "Quote") + P("'") * Cs((V("EscSeq") + (P(1) - S("'\ -"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:660 +"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:693 ["EscSeq"] = P("\\") / "" * (P("a") / "\7" + P("b") / "\8" + P("f") / "\12" + P("n") / "\ " + P("r") / "\13" + P("t") / "\9" + P("v") / "\11" + P("\ ") / "\ " + P("\13") / "\ -" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:690 -["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:693 -return s -- ./candran/can-parser/parser.lua:693 -end, -- ./candran/can-parser/parser.lua:693 +" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:723 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:726 +return s -- ./candran/can-parser/parser.lua:726 +end, -- ./candran/can-parser/parser.lua:726 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 1, -- ./candran/can-parser/parser.lua:694 -["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:695 -["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:696 -["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:697 -return # openEq == # closeEq -- ./candran/can-parser/parser.lua:697 -end), -- ./candran/can-parser/parser.lua:697 -["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:699 -["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:700 -["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:706 -["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:707 -["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:708 -["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:709 -["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:711 -["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:712 -["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:714 -["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:718 -["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:722 -["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:723 -["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:724 -} -- ./candran/can-parser/parser.lua:724 -local parser = {} -- ./candran/can-parser/parser.lua:727 -local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:729 -local validate = validator["validate"] -- ./candran/can-parser/parser.lua:730 -local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:731 -parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:733 -local errorinfo = { -- ./candran/can-parser/parser.lua:734 -["subject"] = subject, -- ./candran/can-parser/parser.lua:734 -["filename"] = filename -- ./candran/can-parser/parser.lua:734 -} -- ./candran/can-parser/parser.lua:734 -lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:735 -local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:736 -if not ast then -- ./candran/can-parser/parser.lua:737 -local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:738 -return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:739 -end -- ./candran/can-parser/parser.lua:739 -return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:741 -end -- ./candran/can-parser/parser.lua:741 -return parser -- ./candran/can-parser/parser.lua:744 -end -- ./candran/can-parser/parser.lua:744 -local parser = _() or parser -- ./candran/can-parser/parser.lua:748 -package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:749 -local candran = { ["VERSION"] = "0.12.0" } -- candran.can:14 -candran["default"] = { -- candran.can:18 -["target"] = "lua53", -- candran.can:19 -["indentation"] = "", -- candran.can:20 +") ^ - 1, -- ./candran/can-parser/parser.lua:727 +["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:728 +["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:729 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:730 +return # openEq == # closeEq -- ./candran/can-parser/parser.lua:730 +end), -- ./candran/can-parser/parser.lua:730 +["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:732 +["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:733 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:739 +["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:740 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:741 +["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:742 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:744 +["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:745 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:747 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:751 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:755 +["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:756 +["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:757 +} -- ./candran/can-parser/parser.lua:757 +local parser = {} -- ./candran/can-parser/parser.lua:760 +local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:762 +local validate = validator["validate"] -- ./candran/can-parser/parser.lua:763 +local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:764 +parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:766 +local errorinfo = { -- ./candran/can-parser/parser.lua:767 +["subject"] = subject, -- ./candran/can-parser/parser.lua:767 +["filename"] = filename -- ./candran/can-parser/parser.lua:767 +} -- ./candran/can-parser/parser.lua:767 +lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:768 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:769 +if not ast then -- ./candran/can-parser/parser.lua:770 +local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:771 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:772 +end -- ./candran/can-parser/parser.lua:772 +return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:774 +end -- ./candran/can-parser/parser.lua:774 +return parser -- ./candran/can-parser/parser.lua:777 +end -- ./candran/can-parser/parser.lua:777 +local parser = _() or parser -- ./candran/can-parser/parser.lua:781 +package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 +local candran = { ["VERSION"] = "0.13.0" } -- candran.can:15 +candran["default"] = { -- candran.can:19 +["target"] = "lua54", -- candran.can:20 +["indentation"] = "", -- candran.can:21 ["newline"] = "\ -", -- candran.can:21 -["variablePrefix"] = "__CAN_", -- candran.can:22 -["mapLines"] = true, -- candran.can:23 -["chunkname"] = "nil", -- candran.can:24 -["rewriteErrors"] = true -- candran.can:25 -} -- candran.can:25 -if _VERSION == "Lua 5.1" then -- candran.can:29 -if package["loaded"]["jit"] then -- candran.can:30 -candran["default"]["target"] = "luajit" -- candran.can:31 -else -- candran.can:31 -candran["default"]["target"] = "lua51" -- candran.can:33 -end -- candran.can:33 -end -- candran.can:33 -candran["preprocess"] = function(input, options) -- candran.can:43 -if options == nil then options = {} end -- candran.can:43 -options = util["merge"](candran["default"], options) -- candran.can:44 -local preprocessor = "" -- candran.can:47 -local i = 0 -- candran.can:48 -local inLongString = false -- candran.can:49 -local inComment = false -- candran.can:50 +", -- candran.can:22 +["variablePrefix"] = "__CAN_", -- candran.can:23 +["mapLines"] = true, -- candran.can:24 +["chunkname"] = "nil", -- candran.can:25 +["rewriteErrors"] = true -- candran.can:26 +} -- candran.can:26 +if _VERSION == "Lua 5.1" then -- candran.can:30 +if package["loaded"]["jit"] then -- candran.can:31 +candran["default"]["target"] = "luajit" -- candran.can:32 +else -- candran.can:32 +candran["default"]["target"] = "lua51" -- candran.can:34 +end -- candran.can:34 +elseif _VERSION == "Lua 5.2" then -- candran.can:36 +candran["default"]["target"] = "lua51" -- candran.can:37 +elseif _VERSION == "Lua 5.3" then -- candran.can:38 + -- candran.can:40 +end -- candran.can:40 +candran["preprocess"] = function(input, options) -- candran.can:48 +if options == nil then options = {} end -- candran.can:48 +options = util["merge"](candran["default"], options) -- candran.can:49 +local preprocessor = "" -- candran.can:52 +local i = 0 -- candran.can:53 +local inLongString = false -- candran.can:54 +local inComment = false -- candran.can:55 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:51 -i = i + (1) -- candran.can:52 -if inComment then -- candran.can:54 -inComment = not line:match("%]%]") -- candran.can:55 -elseif inLongString then -- candran.can:56 -inLongString = not line:match("%]%]") -- candran.can:57 -else -- candran.can:57 -if line:match("[^%-]%[%[") then -- candran.can:59 -inLongString = true -- candran.can:60 -elseif line:match("%-%-%[%[") then -- candran.can:61 -inComment = true -- candran.can:62 -end -- candran.can:62 -end -- candran.can:62 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:65 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:66 -else -- candran.can:66 -local l = line:sub(1, - 2) -- candran.can:68 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:69 +)") do -- candran.can:56 +i = i + (1) -- candran.can:57 +if inComment then -- candran.can:59 +inComment = not line:match("%]%]") -- candran.can:60 +elseif inLongString then -- candran.can:61 +inLongString = not line:match("%]%]") -- candran.can:62 +else -- candran.can:62 +if line:match("[^%-]%[%[") then -- candran.can:64 +inLongString = true -- candran.can:65 +elseif line:match("%-%-%[%[") then -- candran.can:66 +inComment = true -- candran.can:67 +end -- candran.can:67 +end -- candran.can:67 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:70 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:71 +else -- candran.can:71 +local l = line:sub(1, - 2) -- candran.can:73 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:74 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:70 -else -- candran.can:70 +") -- candran.can:75 +else -- candran.can:75 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:72 -end -- candran.can:72 -end -- candran.can:72 -end -- candran.can:72 -preprocessor = preprocessor .. ("return output") -- candran.can:76 -local env = util["merge"](_G, options) -- candran.can:79 -env["candran"] = candran -- candran.can:81 -env["output"] = "" -- candran.can:83 -env["import"] = function(modpath, margs) -- candran.can:90 -if margs == nil then margs = {} end -- candran.can:90 -local filepath = assert(util["search"](modpath, { -- candran.can:91 -"can", -- candran.can:91 -"lua" -- candran.can:91 -}), "No module named \"" .. modpath .. "\"") -- candran.can:91 -local f = io["open"](filepath) -- candran.can:94 -if not f then -- candran.can:95 -error("can't open the module file to import") -- candran.can:95 -end -- candran.can:95 -margs = util["merge"](options, { -- candran.can:97 -["chunkname"] = filepath, -- candran.can:97 -["loadLocal"] = true, -- candran.can:97 -["loadPackage"] = true -- candran.can:97 -}, margs) -- candran.can:97 -local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:98 -f:close() -- candran.can:99 -local modname = modpath:match("[^%.]+$") -- candran.can:102 +") -- candran.can:77 +end -- candran.can:77 +end -- candran.can:77 +end -- candran.can:77 +preprocessor = preprocessor .. ("return output") -- candran.can:81 +local env = util["merge"](_G, options) -- candran.can:84 +env["candran"] = candran -- candran.can:86 +env["output"] = "" -- candran.can:88 +env["import"] = function(modpath, margs) -- candran.can:95 +if margs == nil then margs = {} end -- candran.can:95 +local filepath = assert(util["search"](modpath, { -- candran.can:96 +"can", -- candran.can:96 +"lua" -- candran.can:96 +}), "No module named \"" .. modpath .. "\"") -- candran.can:96 +local f = io["open"](filepath) -- candran.can:99 +if not f then -- candran.can:100 +error("can't open the module file to import") -- candran.can:100 +end -- candran.can:100 +margs = util["merge"](options, { -- candran.can:102 +["chunkname"] = filepath, -- candran.can:102 +["loadLocal"] = true, -- candran.can:102 +["loadPackage"] = true -- candran.can:102 +}, margs) -- candran.can:102 +local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:103 +f:close() -- candran.can:104 +local modname = modpath:match("[^%.]+$") -- candran.can:107 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:111 -end -- candran.can:111 -env["include"] = function(file) -- candran.can:116 -local f = io["open"](file) -- candran.can:117 -if not f then -- candran.can:118 -error("can't open the file " .. file .. " to include") -- candran.can:118 -end -- candran.can:118 -env["write"](f:read("*a")) -- candran.can:119 -f:close() -- candran.can:120 -end -- candran.can:120 -env["write"] = function(...) -- candran.can:124 -env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:125 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:116 +end -- candran.can:116 +env["include"] = function(file) -- candran.can:121 +local f = io["open"](file) -- candran.can:122 +if not f then -- candran.can:123 +error("can't open the file " .. file .. " to include") -- candran.can:123 +end -- candran.can:123 +env["write"](f:read("*a")) -- candran.can:124 +f:close() -- candran.can:125 end -- candran.can:125 -env["placeholder"] = function(name) -- candran.can:129 -if env[name] then -- candran.can:130 -env["write"](env[name]) -- candran.can:131 -end -- candran.can:131 -end -- candran.can:131 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:136 -if not preprocess then -- candran.can:137 -return nil, "in preprocessor: " .. err -- candran.can:138 -end -- candran.can:138 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:141 +env["write"] = function(...) -- candran.can:129 +env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ +") -- candran.can:130 +end -- candran.can:130 +env["placeholder"] = function(name) -- candran.can:134 +if env[name] then -- candran.can:135 +env["write"](env[name]) -- candran.can:136 +end -- candran.can:136 +end -- candran.can:136 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:141 if not preprocess then -- candran.can:142 return nil, "in preprocessor: " .. err -- candran.can:143 end -- candran.can:143 -local success, output = pcall(preprocess) -- candran.can:147 -if not success then -- candran.can:148 -return nil, "in preprocessor: " .. output -- candran.can:149 -end -- candran.can:149 -return output -- candran.can:152 -end -- candran.can:152 -candran["compile"] = function(input, options) -- candran.can:161 -if options == nil then options = {} end -- candran.can:161 -options = util["merge"](candran["default"], options) -- candran.can:162 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:164 -if not ast then -- candran.can:166 -return nil, errmsg -- candran.can:167 -end -- candran.can:167 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:170 -end -- candran.can:170 -candran["make"] = function(code, options) -- candran.can:179 -local r, err = candran["preprocess"](code, options) -- candran.can:180 -if r then -- candran.can:181 -r, err = candran["compile"](r, options) -- candran.can:182 -if r then -- candran.can:183 -return r -- candran.can:184 -end -- candran.can:184 -end -- candran.can:184 -return r, err -- candran.can:187 -end -- candran.can:187 -local errorRewritingActive = false -- candran.can:190 -local codeCache = {} -- candran.can:191 -candran["loadfile"] = function(filepath, env, options) -- candran.can:194 -local f, err = io["open"](filepath) -- candran.can:195 -if not f then -- candran.can:196 -return nil, ("cannot open %s"):format(err) -- candran.can:197 -end -- candran.can:197 -local content = f:read("*a") -- candran.can:199 -f:close() -- candran.can:200 -return candran["load"](content, filepath, env, options) -- candran.can:202 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:146 +if not preprocess then -- candran.can:147 +return nil, "in preprocessor: " .. err -- candran.can:148 +end -- candran.can:148 +local success, output = pcall(preprocess) -- candran.can:152 +if not success then -- candran.can:153 +return nil, "in preprocessor: " .. output -- candran.can:154 +end -- candran.can:154 +return output -- candran.can:157 +end -- candran.can:157 +candran["compile"] = function(input, options) -- candran.can:166 +if options == nil then options = {} end -- candran.can:166 +options = util["merge"](candran["default"], options) -- candran.can:167 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:169 +if not ast then -- candran.can:171 +return nil, errmsg -- candran.can:172 +end -- candran.can:172 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:175 +end -- candran.can:175 +candran["make"] = function(code, options) -- candran.can:184 +local r, err = candran["preprocess"](code, options) -- candran.can:185 +if r then -- candran.can:186 +r, err = candran["compile"](r, options) -- candran.can:187 +if r then -- candran.can:188 +return r -- candran.can:189 +end -- candran.can:189 +end -- candran.can:189 +return r, err -- candran.can:192 +end -- candran.can:192 +local errorRewritingActive = false -- candran.can:195 +local codeCache = {} -- candran.can:196 +candran["loadfile"] = function(filepath, env, options) -- candran.can:199 +local f, err = io["open"](filepath) -- candran.can:200 +if not f then -- candran.can:201 +return nil, ("cannot open %s"):format(err) -- candran.can:202 end -- candran.can:202 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:207 -if options == nil then options = {} end -- candran.can:207 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:208 -local code, err = candran["make"](chunk, options) -- candran.can:210 -if not code then -- candran.can:211 -return code, err -- candran.can:212 -end -- candran.can:212 -codeCache[options["chunkname"]] = code -- candran.can:215 -local f, err = util["load"](code, options["chunkname"], env) -- candran.can:216 -if f == nil then -- candran.can:221 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:222 -end -- candran.can:222 -if options["rewriteErrors"] == false then -- candran.can:225 -return f -- candran.can:226 -else -- candran.can:226 -return function(...) -- candran.can:228 -local params = { ... } -- candran.can:229 -if not errorRewritingActive then -- candran.can:230 -errorRewritingActive = true -- candran.can:231 -local t = { xpcall(function() -- candran.can:232 -return f(unpack(params)) -- candran.can:232 -end, candran["messageHandler"]) } -- candran.can:232 -errorRewritingActive = false -- candran.can:233 -if t[1] == false then -- candran.can:234 -error(t[2], 0) -- candran.can:235 -end -- candran.can:235 -return unpack(t, 2) -- candran.can:237 -else -- candran.can:237 -return f(...) -- candran.can:239 -end -- candran.can:239 -end -- candran.can:239 -end -- candran.can:239 -end -- candran.can:239 -candran["dofile"] = function(filename, options) -- candran.can:247 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:248 -if f == nil then -- candran.can:250 -error(err) -- candran.can:251 -else -- candran.can:251 -return f() -- candran.can:253 -end -- candran.can:253 -end -- candran.can:253 -candran["messageHandler"] = function(message) -- candran.can:259 +local content = f:read("*a") -- candran.can:204 +f:close() -- candran.can:205 +return candran["load"](content, filepath, env, options) -- candran.can:207 +end -- candran.can:207 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:212 +if options == nil then options = {} end -- candran.can:212 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:213 +local code, err = candran["make"](chunk, options) -- candran.can:215 +if not code then -- candran.can:216 +return code, err -- candran.can:217 +end -- candran.can:217 +codeCache[options["chunkname"]] = code -- candran.can:220 +local f, err = util["load"](code, options["chunkname"], env) -- candran.can:221 +if f == nil then -- candran.can:226 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:227 +end -- candran.can:227 +if options["rewriteErrors"] == false then -- candran.can:230 +return f -- candran.can:231 +else -- candran.can:231 +return function(...) -- candran.can:233 +local params = { ... } -- candran.can:234 +if not errorRewritingActive then -- candran.can:235 +errorRewritingActive = true -- candran.can:236 +local t = { xpcall(function() -- candran.can:237 +return f(unpack(params)) -- candran.can:237 +end, candran["messageHandler"]) } -- candran.can:237 +errorRewritingActive = false -- candran.can:238 +if t[1] == false then -- candran.can:239 +error(t[2], 0) -- candran.can:240 +end -- candran.can:240 +return unpack(t, 2) -- candran.can:242 +else -- candran.can:242 +return f(...) -- candran.can:244 +end -- candran.can:244 +end -- candran.can:244 +end -- candran.can:244 +end -- candran.can:244 +candran["dofile"] = function(filename, options) -- candran.can:252 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:253 +if f == nil then -- candran.can:255 +error(err) -- candran.can:256 +else -- candran.can:256 +return f() -- candran.can:258 +end -- candran.can:258 +end -- candran.can:258 +candran["messageHandler"] = function(message) -- candran.can:264 return debug["traceback"](message, 2):gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:260 -line = tonumber(line) -- candran.can:261 -local originalFile -- candran.can:263 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:264 -if strName then -- candran.can:265 -if codeCache[strName] then -- candran.can:266 -originalFile = codeCache[strName] -- candran.can:267 -source = strName -- candran.can:268 -end -- candran.can:268 -else -- candran.can:268 -local fi = io["open"](source, "r") -- candran.can:271 -if fi then -- candran.can:272 -originalFile = fi:read("*a") -- candran.can:273 -fi:close() -- candran.can:274 -end -- candran.can:274 -end -- candran.can:274 -if originalFile then -- candran.can:278 -local i = 0 -- candran.can:279 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:265 +line = tonumber(line) -- candran.can:266 +local originalFile -- candran.can:268 +local strName = source:match("%[string \"(.-)\"%]") -- candran.can:269 +if strName then -- candran.can:270 +if codeCache[strName] then -- candran.can:271 +originalFile = codeCache[strName] -- candran.can:272 +source = strName -- candran.can:273 +end -- candran.can:273 +else -- candran.can:273 +local fi = io["open"](source, "r") -- candran.can:276 +if fi then -- candran.can:277 +originalFile = fi:read("*a") -- candran.can:278 +fi:close() -- candran.can:279 +end -- candran.can:279 +end -- candran.can:279 +if originalFile then -- candran.can:283 +local i = 0 -- candran.can:284 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:280 -i = i + 1 -- candran.can:281 -if i == line then -- candran.can:282 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:283 -if lineMap then -- candran.can:284 -if extSource ~= source then -- candran.can:285 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:286 -else -- candran.can:286 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:288 -end -- candran.can:288 -end -- candran.can:288 -break -- candran.can:291 -end -- candran.can:291 -end -- candran.can:291 -end -- candran.can:291 -end) -- candran.can:291 -end -- candran.can:291 -candran["searcher"] = function(modpath) -- candran.can:299 -local filepath = util["search"](modpath, { "can" }) -- candran.can:300 -if not filepath then -- candran.can:301 +") do -- candran.can:285 +i = i + 1 -- candran.can:286 +if i == line then -- candran.can:287 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:288 +if lineMap then -- candran.can:289 +if extSource ~= source then -- candran.can:290 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:291 +else -- candran.can:291 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:293 +end -- candran.can:293 +end -- candran.can:293 +break -- candran.can:296 +end -- candran.can:296 +end -- candran.can:296 +end -- candran.can:296 +end) -- candran.can:296 +end -- candran.can:296 +candran["searcher"] = function(modpath) -- candran.can:304 +local filepath = util["search"](modpath, { "can" }) -- candran.can:305 +if not filepath then -- candran.can:306 return "\ -\9no candran file in package.path" -- candran.can:302 -end -- candran.can:302 -return candran["loadfile"](filepath) -- candran.can:304 -end -- candran.can:304 -candran["setup"] = function() -- candran.can:308 -if _VERSION == "Lua 5.1" then -- candran.can:309 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:310 -else -- candran.can:310 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:312 -end -- candran.can:312 -return candran -- candran.can:314 -end -- candran.can:314 -return candran -- candran.can:317 +\9no candran file in package.path" -- candran.can:307 +end -- candran.can:307 +return candran["loadfile"](filepath) -- candran.can:309 +end -- candran.can:309 +candran["setup"] = function() -- candran.can:313 +if _VERSION == "Lua 5.1" then -- candran.can:314 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:315 +else -- candran.can:315 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:317 +end -- candran.can:317 +return candran -- candran.can:319 +end -- candran.can:319 +return candran -- candran.can:322 diff --git a/candran/can-parser/parser.lua b/candran/can-parser/parser.lua index 0d17122..6efe5c7 100644 --- a/candran/can-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -14,7 +14,7 @@ stat: | `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... + | `Local{ {attributeident+} {expr+}? } -- local i1, i2... = e1, e2... | `Let{ {ident+} {expr+}? } -- let i1, i2... = e1, e2... | `Localrec{ {ident} {expr} } -- only used for 'local function' | `Goto{ } -- goto str @@ -59,7 +59,7 @@ apply: `Call{ expr expr* } | `SafeCall{ expr expr* } -lhs: `Id{ } | `Index{ expr expr } | ˇDestructuringId{ Id | Pair+ } +lhs: `Id{ } | AttributeId{ ? } | `Index{ expr expr } | ˇDestructuringId{ Id | Pair+ } opid: -- includes additional operators from Lua 5.3 and all relational operators 'add' | 'sub' | 'mul' | 'div' @@ -113,7 +113,9 @@ local labels = { { "ErrDoFor", "expected 'do' after the range of the for loop" }, { "ErrDefLocal", "expected a function definition or assignment after local" }, - { "ErrDefLet", "expected a function definition or assignment after let" }, + { "ErrDefLet", "expected an assignment after let" }, + { "ErrDefClose", "expected an assignment after close" }, + { "ErrDefConst", "expected an assignment after const" }, { "ErrNameLFunc", "expected a function name after 'function'" }, { "ErrEListLAssign", "expected one or more expressions after '='" }, { "ErrEListAssign", "expected one or more expressions after '='" }, @@ -181,6 +183,9 @@ local labels = { { "ErrCBraceUEsc", "expected '}' after the code point" }, { "ErrEscSeq", "invalid escape sequence" }, { "ErrCloseLStr", "unclosed long string" }, + + { "ErrUnknownAttribute", "unknown variable attribute" }, + { "ErrCBracketAttribute", "expected '>' to close the variable attribute" }, } local function throw(label) @@ -456,6 +461,24 @@ local function maybe (patt) -- fail pattern instead of propagating errors return #patt/0 * patt end +local function setAttribute(attribute) + return function(assign) + assign[1].tag = "AttributeNameList" + for _, id in ipairs(assign[1]) do + if id.tag == "Id" then + id.tag = "AttributeId" + id[2] = attribute + elseif id.tag == "DestructuringId" then + for _, did in ipairs(id) do + did.tag = "AttributeId" + did[2] = attribute + end + end + end + return assign + end +end + local stacks = { lexpr = {} } @@ -488,7 +511,7 @@ local G = { V"Lua", Block = tagC("Block", (V"Stat" + -V"BlockEnd" * throw("InvalidStat"))^0 * ((V"RetStat" + V"ImplicitPushStat") * sym(";")^-1)^-1); Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat" + V"LocalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat" - + V"LetStat" + + V"LetStat" + V"ConstStat" + V"CloseStat" + V"FuncCall" + V"Assignment" + V"ContinueStat" + V"PushStat" + sym(";"); @@ -516,13 +539,18 @@ local G = { V"Lua", LocalStat = kw("local") * expect(V"LocalFunc" + V"LocalAssign", "DefLocal"); LocalFunc = tagC("Localrec", kw("function") * expect(V"Id", "NameLFunc") * V"FuncBody") / fixFuncStat; - LocalAssign = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + LocalAssign = tagC("Local", V"AttributeNameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + tagC("Local", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); LetStat = kw("let") * expect(V"LetAssign", "DefLet"); LetAssign = tagC("Let", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + tagC("Let", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); + ConstStat = kw("const") * expect(V"AttributeAssign" / setAttribute("const"), "DefConst"); + CloseStat = kw("close") * expect(V"AttributeAssign" / setAttribute("close"), "DefClose"); + AttributeAssign = tagC("Local", V"NameList" * (sym("=") * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) + + tagC("Local", V"DestructuringNameList" * sym("=") * expect(V"ExprList", "EListLAssign")); + Assignment = tagC("Set", (V"VarList" + V"DestructuringNameList") * V"BinOp"^-1 * (P"=" / "=") * ((V"BinOp" - P"-") + #(P"-" * V"Space") * V"BinOp")^-1 * V"Skip" * expect(V"ExprList", "EListAssign")); FuncStat = tagC("Set", kw("function") * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat; @@ -551,8 +579,9 @@ local G = { V"Lua", PushStat = tagC("Push", kw("push") * commaSep(V"Expr", "RetList")^-1); ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList")); - NameList = tagC("NameList", commaSep(V"Id")); + NameList = tagC("NameList", commaSep(V"Id")); DestructuringNameList = tagC("NameList", commaSep(V"DestructuringId")), + AttributeNameList = tagC("AttributeNameList", commaSep(V"AttributeId")); VarList = tagC("VarList", commaSep(V"VarExpr")); ExprList = tagC("ExpList", commaSep(V"Expr", "ExprList")); @@ -626,8 +655,12 @@ local G = { V"Lua", SelfId = tagC("Id", sym"@" / "self"); Id = tagC("Id", V"Name") + V"SelfId"; + AttributeSelfId = tagC("AttributeId", sym"@" / "self" * V"Attribute"^-1); + AttributeId = tagC("AttributeId", V"Name" * V"Attribute"^-1) + V"AttributeSelfId"; StrId = tagC("String", V"Name"); + Attribute = sym("<") * expect(kw"const" / "const" + kw"close" / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"); + -- lexer Skip = (V"Space" + V"Comment")^0; Space = space^1; diff --git a/compiler/lua53.can b/compiler/lua53.can index 5dabc03..1bb0c53 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -1,827 +1,10 @@ -local targetName = "Lua 5.3" +targetName = "Lua 5.3" -return function(code, ast, options) - --- Line mapping - local lastInputPos = 1 -- last token position in the input code - local prevLinePos = 1 -- last token position in the previous line of code in the input code - local lastSource = options.chunkname or "nil" -- last found code source name (from the original file) - local lastLine = 1 -- last found line number (from the original file) +-- Unsuported features +tags.AttributeId = nil - --- Newline management - local indentLevel = 0 - -- Returns a newline. - local function newline() - local r = options.newline..string.rep(options.indentation, indentLevel) - if options.mapLines then - local sub = code:sub(lastInputPos) - local source, line = sub:sub(1, sub:find("\n")):match(".*%-%- (.-)%:(%d+)\n") +#local patch = output +#output = "" +#import("compiler.lua54", { patch = patch, loadPackage = false }) - if source and line then - lastSource = source - lastLine = tonumber(line) - else - for _ in code:sub(prevLinePos, lastInputPos):gmatch("\n") do - lastLine += 1 - end - end - - prevLinePos = lastInputPos - - r = " -- "..lastSource..":"..lastLine..r - end - return r - end - -- Returns a newline and add one level of indentation. - local function indent() - indentLevel += 1 - return newline() - end - -- Returns a newline and remove one level of indentation. - local function unindent() - indentLevel -= 1 - return newline() - end - - --- State stacks - -- Used for context-sensitive syntax. - local states = { - push = {}, -- push stack variable names - destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} - scope = {} -- list of variables defined in the current scope - } - -- Push a new value on top of the stack "name". Returns an empty string for chaining. - local function push(name, state) - table.insert(states[name], state) - return "" - end - -- Remove the value on top of the stack "name". Returns an empty string for chaining. - local function pop(name) - table.remove(states[name]) - return "" - end - -- Set the value on top of the stack "name". Returns an empty string for chaining. - local function set(name, state) - states[name][#states[name]] = state - return "" - end - -- Returns the value on top of the stack "name". - local function peek(name) - return states[name][#states[name]] - end - - --- Variable management - -- Returns the prefixed variable name. - local function var(name) - return options.variablePrefix..name - end - - -- Returns the prefixed temporary variable name. - local function tmp() - local scope = peek("scope") - local var = "%s_%s":format(options.variablePrefix, #scope) - table.insert(scope, var) - return var - end - - --- Module management - local required = {} -- { ["full require expression"] = true, ... } - local requireStr = "" - -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". - local function addRequire(mod, name, field) - local req = "require(%q)%s":format(mod, field and "."..field or "") - if not required[req] then - requireStr ..= "local %s = %s%s":format(var(name), req, options.newline) - required[req] = true - end - end - - --- AST traversal helpers - local loop = { "While", "Repeat", "Fornum", "Forin", "WhileExpr", "RepeatExpr", "FornumExpr", "ForinExpr" } -- loops tags (can contain continue) - local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags (can contain push) - - -- Returns the first node or subnode from the list "list" which tag is in the list "tags", or nil if there were none. - -- Won't recursively follow nodes which have a tag in "nofollow". - local function any(list, tags, nofollow={}) - local tagsCheck = {} - for _, tag in ipairs(tags) do - tagsCheck[tag] = true - end - local nofollowCheck = {} - for _, tag in ipairs(nofollow) do - nofollowCheck[tag] = true - end - for _, node in ipairs(list) do - if type(node) == "table" then - if tagsCheck[node.tag] then - return node - end - if not nofollowCheck[node.tag] then - local r = any(node, tags, nofollow) - if r then return r end - end - end - end - return nil - end - - -- Like any, but returns a list of every node found. - -- Order: in the order of the list, from the deepest to the nearest - local function search(list, tags, nofollow={}) - local tagsCheck = {} - for _, tag in ipairs(tags) do - tagsCheck[tag] = true - end - local nofollowCheck = {} - for _, tag in ipairs(nofollow) do - nofollowCheck[tag] = true - end - local found = {} - for _, node in ipairs(list) do - if type(node) == "table" then - if not nofollowCheck[node.tag] then - for _, n in ipairs(search(node, tags, nofollow)) do - table.insert(found, n) - end - end - if tagsCheck[node.tag] then - table.insert(found, node) - end - end - end - return found - end - - -- Returns true if the all the nodes in list have their type in tags. - local function all(list, tags) - for _, node in ipairs(list) do - local ok = false - for _, tag in ipairs(tags) do - if node.tag == tag then - ok = true - break - end - end - if not ok then - return false - end - end - return true - end - - --- Lua compiler - local tags - -- Recursively returns the compiled AST Lua code, set "forceTag" to override the tag type and pass additional arguments to the tag constructor if needed. - local function lua(ast, forceTag, ...) - if options.mapLines and ast.pos then - lastInputPos = ast.pos - end - return tags[forceTag or ast.tag](ast, ...) - end - - --- Lua function calls writer - local UNPACK = (list, i, j) -- table.unpack - return "table.unpack("..list..(i and (", "..i..(j and (", "..j) or "")) or "")..")" - end - local APPEND = (t, toAppend) -- append values "toAppend" (multiple values possible) to t - return "do"..indent().."local "..var("a").." = table.pack("..toAppend..")"..newline().."table.move("..var("a")..", 1, "..var("a")..".n, #"..t.."+1, "..t..")"..unindent().."end" - end - local CONTINUE_START = () -- at the start of loops using continue - return "do"..indent() - end - local CONTINUE_STOP = () -- at the start of loops using continue - return unindent().."end"..newline().."::"..var"continue".."::" - end - local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement - local vars = {} - local values = {} - for _, list in ipairs(destructured) do - for _, v in ipairs(list) do - local var, val - if v.tag == "Id" then - var = v - val = { tag = "Index", { tag = "Id", list.id }, { tag = "String", v[1] } } - elseif v.tag == "Pair" then - var = v[2] - val = { tag = "Index", { tag = "Id", list.id }, v[1] } - else - error("unknown destructuring element type: "..tostring(v.tag)) - end - if destructured.rightOp and destructured.leftOp then - val = { tag = "Op", destructured.rightOp, var, { tag = "Op", destructured.leftOp, val, var } } - elseif destructured.rightOp then - val = { tag = "Op", destructured.rightOp, var, val } - elseif destructured.leftOp then - val = { tag = "Op", destructured.leftOp, val, var } - end - table.insert(vars, lua(var)) - table.insert(values, lua(val)) - end - end - if #vars > 0 then - local decl = noLocal and "" or "local " - if newlineAfter then - return decl..table.concat(vars, ", ").." = "..table.concat(values, ", ")..newline() - else - return newline()..decl..table.concat(vars, ", ").." = "..table.concat(values, ", ") - end - else - return "" - end - end - - --- Tag constructors - tags = setmetatable({ - -- block: { stat* } -- - Block = (t) - local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined - if hasPush and hasPush == t[#t] then -- if the first push is the last statement, it's just a return - hasPush.tag = "Return" - hasPush = false - end - local r = push("scope", {}) - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - end - for i=1, #t-1, 1 do - r ..= lua(t[i])..newline() - end - if t[#t] then - r ..= lua(t[#t]) - end - if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed - r ..= newline().."return "..UNPACK(var"push")..pop("push") - end - return r..pop("scope") - end, - - -- stat -- - - -- Do{ stat* } - Do = (t) - return "do"..indent()..lua(t, "Block")..unindent().."end" - end, - -- Set{ {lhs+} (opid? = opid?)? {expr+} } - Set = (t) - -- extract vars and values - local expr = t[#t] - local vars, values = {}, {} - local destructuringVars, destructuringValues = {}, {} - for i, n in ipairs(t[1]) do - if n.tag == "DestructuringId" then - table.insert(destructuringVars, n) - table.insert(destructuringValues, expr[i]) - else - table.insert(vars, n) - table.insert(values, expr[i]) - end - end - -- - if #t == 2 or #t == 3 then - local r = "" - if #vars > 0 then - r = lua(vars, "_lhs").." = "..lua(values, "_lhs") - end - if #destructuringVars > 0 then - local destructured = {} - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - elseif #t == 4 then - if t[3] == "=" then - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Paren", values[1] } }, "Op") - for i=2, math.min(#t[4], #vars), 1 do - r ..= ", "..lua({ t[2], vars[i], { tag = "Paren", values[i] } }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { rightOp = t[2] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - else - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[3], { tag = "Paren", values[1] }, vars[1] }, "Op") - for i=2, math.min(#t[4], #t[1]), 1 do - r ..= ", "..lua({ t[3], { tag = "Paren", values[i] }, vars[i] }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { leftOp = t[3] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - end - else -- You are mad. - local r = "" - if #vars > 0 then - r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Op", t[4], { tag = "Paren", values[1] }, vars[1] } }, "Op") - for i=2, math.min(#t[5], #t[1]), 1 do - r ..= ", "..lua({ t[2], vars[i], { tag = "Op", t[4], { tag = "Paren", values[i] }, vars[i] } }, "Op") - end - end - if #destructuringVars > 0 then - local destructured = { rightOp = t[2], leftOp = t[4] } - r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") - return r..DESTRUCTURING_ASSIGN(destructured, nil, true) - end - return r - end - end, - -- While{ expr block } - While = (t) - local r = "" - local hasContinue = any(t[2], { "Continue" }, loop) - local lets = search({ t[1] }, { "LetExpr" }) - if #lets > 0 then - r ..= "do"..indent() - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - end - r ..= "while "..lua(t[1]).." do"..indent() - if #lets > 0 then - r ..= "do"..indent() - end - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[2]) - if hasContinue then - r ..= CONTINUE_STOP() - end - r ..= unindent().."end" - if #lets > 0 then - for _, l in ipairs(lets) do - r ..= newline()..lua(l, "Set") - end - r ..= unindent().."end"..unindent().."end" - end - return r - end, - -- Repeat{ block expr } - Repeat = (t) - local hasContinue = any(t[1], { "Continue" }, loop) - local r = "repeat"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[1]) - if hasContinue then - r ..= CONTINUE_STOP() - end - r ..= unindent().."until "..lua(t[2]) - return r - end, - -- If{ (lexpr block)+ block? } - If = (t) - local r = "" - local toClose = 0 -- blocks that need to be closed at the end of the if - local lets = search({ t[1] }, { "LetExpr" }) - if #lets > 0 then - r ..= "do"..indent() - toClose += 1 - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - end - r ..= "if "..lua(t[1]).." then"..indent()..lua(t[2])..unindent() - for i=3, #t-1, 2 do - lets = search({ t[i] }, { "LetExpr" }) - if #lets > 0 then - r ..= "else"..indent() - toClose += 1 - for _, l in ipairs(lets) do - r ..= lua(l, "Let")..newline() - end - else - r ..= "else" - end - r ..= "if "..lua(t[i]).." then"..indent()..lua(t[i+1])..unindent() - end - if #t % 2 == 1 then - r ..= "else"..indent()..lua(t[#t])..unindent() - end - r ..= "end" - for i=1, toClose do - r ..= unindent().."end" - end - return r - end, - -- Fornum{ ident expr expr expr? block } - Fornum = (t) - local r = "for "..lua(t[1]).." = "..lua(t[2])..", "..lua(t[3]) - if #t == 5 then - local hasContinue = any(t[5], { "Continue" }, loop) - r ..= ", "..lua(t[4]).." do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[5]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - else - local hasContinue = any(t[4], { "Continue" }, loop) - r ..= " do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= lua(t[4]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - end - end, - -- Forin{ {ident+} {expr+} block } - Forin = (t) - local destructured = {} - local hasContinue = any(t[3], { "Continue" }, loop) - local r = "for "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring").." in "..lua(t[2], "_lhs").." do"..indent() - if hasContinue then - r ..= CONTINUE_START() - end - r ..= DESTRUCTURING_ASSIGN(destructured, true)..lua(t[3]) - if hasContinue then - r ..= CONTINUE_STOP() - end - return r..unindent().."end" - end, - -- Local{ {ident+} {expr+}? } - Local = (t) - local destructured = {} - local r = "local "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") - if t[2][1] then - r ..= " = "..lua(t[2], "_lhs") - end - return r..DESTRUCTURING_ASSIGN(destructured) - end, - -- Let{ {ident+} {expr+}? } - Let = (t) - local destructured = {} - local nameList = push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") - local r = "local "..nameList - if t[2][1] then - if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here - r ..= " = "..lua(t[2], "_lhs") - else - r ..= newline()..nameList.." = "..lua(t[2], "_lhs") - end - end - return r..DESTRUCTURING_ASSIGN(destructured) - end, - -- Localrec{ {ident} {expr} } - Localrec = (t) - return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") - end, - -- Goto{ } - Goto = (t) - return "goto "..lua(t, "Id") - end, - -- Label{ } - Label = (t) - return "::"..lua(t, "Id").."::" - end, - -- Return{ } - Return = (t) - local push = peek("push") - if push then - local r = "" - for _, val in ipairs(t) do - r ..= push.."[#"..push.."+1] = "..lua(val)..newline() - end - return r.."return "..UNPACK(push) - else - return "return "..lua(t, "_lhs") - end - end, - -- Push{ } - Push = (t) - local var = assert(peek("push"), "no context given for push") - r = "" - for i=1, #t-1, 1 do - r ..= var.."[#"..var.."+1] = "..lua(t[i])..newline() - end - if t[#t] then - if t[#t].tag == "Call" then - r ..= APPEND(var, lua(t[#t])) - else - r ..= var.."[#"..var.."+1] = "..lua(t[#t]) - end - end - return r - end, - -- Break - Break = () - return "break" - end, - -- Continue - Continue = () - return "goto "..var"continue" - end, - -- apply (below) - - -- expr -- - - -- Nil - Nil = () - return "nil" - end, - -- Dots - Dots = () - return "..." - end, - -- Boolean{ } - Boolean = (t) - return tostring(t[1]) - end, - -- Number{ } - Number = (t) - return tostring(t[1]) - end, - -- String{ } - String = (t) - return "%q":format(t[1]) - end, - -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } - _functionWithoutKeyword = (t) - local r = "(" - local decl = {} - if t[1][1] then - if t[1][1].tag == "ParPair" then - local id = lua(t[1][1][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") - indentLevel -= 1 - r ..= id - else - r ..= lua(t[1][1]) - end - for i=2, #t[1], 1 do - if t[1][i].tag == "ParPair" then - local id = lua(t[1][i][1]) - indentLevel += 1 - table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") - indentLevel -= 1 - r ..= ", " ..id - else - r ..= ", "..lua(t[1][i]) - end - end - end - r ..= ")"..indent() - for _, d in ipairs(decl) do - r ..= d..newline() - end - if t[2][#t[2]] and t[2][#t[2]].tag == "Push" then -- convert final push to return - t[2][#t[2]].tag = "Return" - end - local hasPush = any(t[2], { "Push" }, func) - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - else - push("push", false) -- no push here (make sure higher push doesn't affect us) - end - r ..= lua(t[2]) - if hasPush and (t[2][#t[2]] and t[2][#t[2]].tag ~= "Return") then -- add return only if needed - r ..= newline().."return "..UNPACK(var"push") - end - pop("push") - return r..unindent().."end" - end, - Function = (t) - return "function"..lua(t, "_functionWithoutKeyword") - end, - -- Table{ ( `Pair{ expr expr } | expr )* } - Pair = (t) - return "["..lua(t[1]).."] = "..lua(t[2]) - end, - Table = (t) - if #t == 0 then - return "{}" - elseif #t == 1 then - return "{ "..lua(t, "_lhs").." }" - else - return "{"..indent()..lua(t, "_lhs", nil, true)..unindent().."}" - end - end, - -- TableCompr{ block } - TableCompr = (t) - return push("push", "self").."(function()"..indent().."local self = {}"..newline()..lua(t[1])..newline().."return self"..unindent().."end)()"..pop("push") - end, - -- Op{ opid expr expr? } - Op = (t) - local r - if #t == 2 then - if type(tags._opid[t[1]]) == "string" then - r = tags._opid[t[1]].." "..lua(t[2]) - else - r = tags._opid[t[1]](t[2]) - end - else - if type(tags._opid[t[1]]) == "string" then - r = lua(t[2]).." "..tags._opid[t[1]].." "..lua(t[3]) - else - r = tags._opid[t[1]](t[2], t[3]) - end - end - return r - end, - -- Paren{ expr } - Paren = (t) - return "("..lua(t[1])..")" - end, - -- MethodStub{ expr expr } - MethodStub = (t) - return "(function()"..indent() .. - "local "..var"object".." = "..lua(t[1])..newline().. - "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. - "if "..var"method".." == nil then return nil end"..newline().. - "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. - "end)()" - end, - -- SafeMethodStub{ expr expr } - SafeMethodStub = (t) - return "(function()"..indent() .. - "local "..var"object".." = "..lua(t[1])..newline().. - "if "..var"object".." == nil then return nil end"..newline().. - "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. - "if "..var"method".." == nil then return nil end"..newline().. - "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. - "end)()" - end, - -- statexpr (below) - -- apply (below) - -- lhs (below) - - -- lexpr -- - LetExpr = (t) - return lua(t[1][1]) - end, - - -- statexpr -- - _statexpr = (t, stat) - local hasPush = any(t, { "Push" }, func) - local r = "(function()"..indent() - if hasPush then - r ..= push("push", var"push").."local "..var"push".." = {}"..newline() - else - push("push", false) -- no push here (make sure higher push don't affect us) - end - r ..= lua(t, stat) - if hasPush then - r ..= newline().."return "..UNPACK(var"push") - end - pop("push") - r ..= unindent().."end)()" - return r - end, - -- DoExpr{ stat* } - DoExpr = (t) - if t[#t].tag == "Push" then -- convert final push to return - t[#t].tag = "Return" - end - return lua(t, "_statexpr", "Do") - end, - -- WhileExpr{ expr block } - WhileExpr = (t) - return lua(t, "_statexpr", "While") - end, - -- RepeatExpr{ block expr } - RepeatExpr = (t) - return lua(t, "_statexpr", "Repeat") - end, - -- IfExpr{ (expr block)+ block? } - IfExpr = (t) - for i=2, #t do -- convert final pushes to returns - local block = t[i] - if block[#block] and block[#block].tag == "Push" then - block[#block].tag = "Return" - end - end - return lua(t, "_statexpr", "If") - end, - -- FornumExpr{ ident expr expr expr? block } - FornumExpr = (t) - return lua(t, "_statexpr", "Fornum") - end, - -- ForinExpr{ {ident+} {expr+} block } - ForinExpr = (t) - return lua(t, "_statexpr", "Forin") - end, - - -- apply -- - - -- Call{ expr expr* } - Call = (t) - if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" - elseif t[1].tag == "MethodStub" then -- method call - if t[1][1].tag == "String" or t[1][1].tag == "Table" then - return "("..lua(t[1][1]).."):"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" - else - return lua(t[1][1])..":"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" - end - else - return lua(t[1]).."("..lua(t, "_lhs", 2)..")" - end - end, - -- SafeCall{ expr expr* } - SafeCall = (t) - if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) - return lua(t, "SafeIndex") - else -- no side effects possible - return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."("..lua(t, "_lhs", 2)..") or nil)" - end - end, - - -- lhs -- - _lhs = (t, start=1, newlines) - local r - if t[start] then - r = lua(t[start]) - for i=start+1, #t, 1 do - r ..= ","..(newlines and newline() or " ")..lua(t[i]) - end - else - r = "" - end - return r - end, - -- Id{ } - Id = (t) - return t[1] - end, - -- DestructuringId{ Id | Pair+ } - DestructuringId = (t) - if t.id then -- destructing already done before, use parent variable as id - return t.id - else - local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") - local vars = { id = tmp() } - for j=1, #t, 1 do - table.insert(vars, t[j]) - end - table.insert(d, vars) - t.id = vars.id - return vars.id - end - end, - -- Index{ expr expr } - Index = (t) - if t[1].tag == "String" or t[1].tag == "Table" then - return "("..lua(t[1])..")["..lua(t[2]).."]" - else - return lua(t[1]).."["..lua(t[2]).."]" - end - end, - -- SafeIndex{ expr expr } - SafeIndex = (t) - if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) - local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) - while t.tag == "SafeIndex" or t.tag == "SafeCall" do - table.insert(l, 1, t) - t = t[1] - end - local r = "(function()"..indent().."local "..var"safe".." = "..lua(l[1][1])..newline() -- base expr - for _, e in ipairs(l) do - r ..= "if "..var"safe".." == nil then return nil end"..newline() - if e.tag == "SafeIndex" then - r ..= var"safe".." = "..var"safe".."["..lua(e[2]).."]"..newline() - else - r ..= var"safe".." = "..var"safe".."("..lua(e, "_lhs", 2)..")"..newline() - end - end - r ..= "return "..var"safe"..unindent().."end)()" - return r - else -- no side effects possible - return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."["..lua(t[2]).."] or nil)" - end - end, - - -- opid -- - _opid = { - add = "+", sub = "-", mul = "*", div = "/", - idiv = "//", mod = "%", pow = "^", concat = "..", - band = "&", bor = "|", bxor = "~", shl = "<<", shr = ">>", - eq = "==", ne = "~=", lt = "<", gt = ">", le = "<=", ge = ">=", - ["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not" - } - }, { - __index = (self, key) - error("don't know how to compile a "..tostring(key).." to "..targetName) - end - }) - - #placeholder("patch") - - local code = lua(ast)..newline() - return requireStr..code -end +return lua54 diff --git a/compiler/lua54.can b/compiler/lua54.can new file mode 100644 index 0000000..6ce91a8 --- /dev/null +++ b/compiler/lua54.can @@ -0,0 +1,835 @@ +local targetName = "Lua 5.4" + +return function(code, ast, options) + --- Line mapping + local lastInputPos = 1 -- last token position in the input code + local prevLinePos = 1 -- last token position in the previous line of code in the input code + local lastSource = options.chunkname or "nil" -- last found code source name (from the original file) + local lastLine = 1 -- last found line number (from the original file) + + --- Newline management + local indentLevel = 0 + -- Returns a newline. + local function newline() + local r = options.newline..string.rep(options.indentation, indentLevel) + if options.mapLines then + local sub = code:sub(lastInputPos) + local source, line = sub:sub(1, sub:find("\n")):match(".*%-%- (.-)%:(%d+)\n") + + if source and line then + lastSource = source + lastLine = tonumber(line) + else + for _ in code:sub(prevLinePos, lastInputPos):gmatch("\n") do + lastLine += 1 + end + end + + prevLinePos = lastInputPos + + r = " -- "..lastSource..":"..lastLine..r + end + return r + end + -- Returns a newline and add one level of indentation. + local function indent() + indentLevel += 1 + return newline() + end + -- Returns a newline and remove one level of indentation. + local function unindent() + indentLevel -= 1 + return newline() + end + + --- State stacks + -- Used for context-sensitive syntax. + local states = { + push = {}, -- push stack variable names + destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} + scope = {} -- list of variables defined in the current scope + } + -- Push a new value on top of the stack "name". Returns an empty string for chaining. + local function push(name, state) + table.insert(states[name], state) + return "" + end + -- Remove the value on top of the stack "name". Returns an empty string for chaining. + local function pop(name) + table.remove(states[name]) + return "" + end + -- Set the value on top of the stack "name". Returns an empty string for chaining. + local function set(name, state) + states[name][#states[name]] = state + return "" + end + -- Returns the value on top of the stack "name". + local function peek(name) + return states[name][#states[name]] + end + + --- Variable management + -- Returns the prefixed variable name. + local function var(name) + return options.variablePrefix..name + end + + -- Returns the prefixed temporary variable name. + local function tmp() + local scope = peek("scope") + local var = "%s_%s":format(options.variablePrefix, #scope) + table.insert(scope, var) + return var + end + + --- Module management + local required = {} -- { ["full require expression"] = true, ... } + local requireStr = "" + -- Add the module "mod" to the list of modules to require, and load its field "field" (or the whole module if nil) into the variable "name". + local function addRequire(mod, name, field) + local req = "require(%q)%s":format(mod, field and "."..field or "") + if not required[req] then + requireStr ..= "local %s = %s%s":format(var(name), req, options.newline) + required[req] = true + end + end + + --- AST traversal helpers + local loop = { "While", "Repeat", "Fornum", "Forin", "WhileExpr", "RepeatExpr", "FornumExpr", "ForinExpr" } -- loops tags (can contain continue) + local func = { "Function", "TableCompr", "DoExpr", "WhileExpr", "RepeatExpr", "IfExpr", "FornumExpr", "ForinExpr" } -- function scope tags (can contain push) + + -- Returns the first node or subnode from the list "list" which tag is in the list "tags", or nil if there were none. + -- Won't recursively follow nodes which have a tag in "nofollow". + local function any(list, tags, nofollow={}) + local tagsCheck = {} + for _, tag in ipairs(tags) do + tagsCheck[tag] = true + end + local nofollowCheck = {} + for _, tag in ipairs(nofollow) do + nofollowCheck[tag] = true + end + for _, node in ipairs(list) do + if type(node) == "table" then + if tagsCheck[node.tag] then + return node + end + if not nofollowCheck[node.tag] then + local r = any(node, tags, nofollow) + if r then return r end + end + end + end + return nil + end + + -- Like any, but returns a list of every node found. + -- Order: in the order of the list, from the deepest to the nearest + local function search(list, tags, nofollow={}) + local tagsCheck = {} + for _, tag in ipairs(tags) do + tagsCheck[tag] = true + end + local nofollowCheck = {} + for _, tag in ipairs(nofollow) do + nofollowCheck[tag] = true + end + local found = {} + for _, node in ipairs(list) do + if type(node) == "table" then + if not nofollowCheck[node.tag] then + for _, n in ipairs(search(node, tags, nofollow)) do + table.insert(found, n) + end + end + if tagsCheck[node.tag] then + table.insert(found, node) + end + end + end + return found + end + + -- Returns true if the all the nodes in list have their type in tags. + local function all(list, tags) + for _, node in ipairs(list) do + local ok = false + for _, tag in ipairs(tags) do + if node.tag == tag then + ok = true + break + end + end + if not ok then + return false + end + end + return true + end + + --- Lua compiler + local tags + -- Recursively returns the compiled AST Lua code, set "forceTag" to override the tag type and pass additional arguments to the tag constructor if needed. + local function lua(ast, forceTag, ...) + if options.mapLines and ast.pos then + lastInputPos = ast.pos + end + return tags[forceTag or ast.tag](ast, ...) + end + + --- Lua function calls writer + local UNPACK = (list, i, j) -- table.unpack + return "table.unpack("..list..(i and (", "..i..(j and (", "..j) or "")) or "")..")" + end + local APPEND = (t, toAppend) -- append values "toAppend" (multiple values possible) to t + return "do"..indent().."local "..var("a").." = table.pack("..toAppend..")"..newline().."table.move("..var("a")..", 1, "..var("a")..".n, #"..t.."+1, "..t..")"..unindent().."end" + end + local CONTINUE_START = () -- at the start of loops using continue + return "do"..indent() + end + local CONTINUE_STOP = () -- at the start of loops using continue + return unindent().."end"..newline().."::"..var"continue".."::" + end + local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement + local vars = {} + local values = {} + for _, list in ipairs(destructured) do + for _, v in ipairs(list) do + local var, val + if v.tag == "Id" or v.tag == "AttributeId" then + var = v + val = { tag = "Index", { tag = "Id", list.id }, { tag = "String", v[1] } } + elseif v.tag == "Pair" then + var = v[2] + val = { tag = "Index", { tag = "Id", list.id }, v[1] } + else + error("unknown destructuring element type: "..tostring(v.tag)) + end + if destructured.rightOp and destructured.leftOp then + val = { tag = "Op", destructured.rightOp, var, { tag = "Op", destructured.leftOp, val, var } } + elseif destructured.rightOp then + val = { tag = "Op", destructured.rightOp, var, val } + elseif destructured.leftOp then + val = { tag = "Op", destructured.leftOp, val, var } + end + table.insert(vars, lua(var)) + table.insert(values, lua(val)) + end + end + if #vars > 0 then + local decl = noLocal and "" or "local " + if newlineAfter then + return decl..table.concat(vars, ", ").." = "..table.concat(values, ", ")..newline() + else + return newline()..decl..table.concat(vars, ", ").." = "..table.concat(values, ", ") + end + else + return "" + end + end + + --- Tag constructors + tags = setmetatable({ + -- block: { stat* } -- + Block = (t) + local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- push in block and push context not yet defined + if hasPush and hasPush == t[#t] then -- if the first push is the last statement, it's just a return + hasPush.tag = "Return" + hasPush = false + end + local r = push("scope", {}) + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + end + for i=1, #t-1, 1 do + r ..= lua(t[i])..newline() + end + if t[#t] then + r ..= lua(t[#t]) + end + if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed + r ..= newline().."return "..UNPACK(var"push")..pop("push") + end + return r..pop("scope") + end, + + -- stat -- + + -- Do{ stat* } + Do = (t) + return "do"..indent()..lua(t, "Block")..unindent().."end" + end, + -- Set{ {lhs+} (opid? = opid?)? {expr+} } + Set = (t) + -- extract vars and values + local expr = t[#t] + local vars, values = {}, {} + local destructuringVars, destructuringValues = {}, {} + for i, n in ipairs(t[1]) do + if n.tag == "DestructuringId" then + table.insert(destructuringVars, n) + table.insert(destructuringValues, expr[i]) + else + table.insert(vars, n) + table.insert(values, expr[i]) + end + end + -- + if #t == 2 or #t == 3 then + local r = "" + if #vars > 0 then + r = lua(vars, "_lhs").." = "..lua(values, "_lhs") + end + if #destructuringVars > 0 then + local destructured = {} + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + elseif #t == 4 then + if t[3] == "=" then + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Paren", values[1] } }, "Op") + for i=2, math.min(#t[4], #vars), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Paren", values[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + else + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[3], { tag = "Paren", values[1] }, vars[1] }, "Op") + for i=2, math.min(#t[4], #t[1]), 1 do + r ..= ", "..lua({ t[3], { tag = "Paren", values[i] }, vars[i] }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { leftOp = t[3] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + end + else -- You are mad. + local r = "" + if #vars > 0 then + r ..= lua(vars, "_lhs").." = "..lua({ t[2], vars[1], { tag = "Op", t[4], { tag = "Paren", values[1] }, vars[1] } }, "Op") + for i=2, math.min(#t[5], #t[1]), 1 do + r ..= ", "..lua({ t[2], vars[i], { tag = "Op", t[4], { tag = "Paren", values[i] }, vars[i] } }, "Op") + end + end + if #destructuringVars > 0 then + local destructured = { rightOp = t[2], leftOp = t[4] } + r ..= "local "..push("destructuring", destructured)..lua(destructuringVars, "_lhs")..pop("destructuring").." = "..lua(destructuringValues, "_lhs") + return r..DESTRUCTURING_ASSIGN(destructured, nil, true) + end + return r + end + end, + -- While{ expr block } + While = (t) + local r = "" + local hasContinue = any(t[2], { "Continue" }, loop) + local lets = search({ t[1] }, { "LetExpr" }) + if #lets > 0 then + r ..= "do"..indent() + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + end + r ..= "while "..lua(t[1]).." do"..indent() + if #lets > 0 then + r ..= "do"..indent() + end + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[2]) + if hasContinue then + r ..= CONTINUE_STOP() + end + r ..= unindent().."end" + if #lets > 0 then + for _, l in ipairs(lets) do + r ..= newline()..lua(l, "Set") + end + r ..= unindent().."end"..unindent().."end" + end + return r + end, + -- Repeat{ block expr } + Repeat = (t) + local hasContinue = any(t[1], { "Continue" }, loop) + local r = "repeat"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[1]) + if hasContinue then + r ..= CONTINUE_STOP() + end + r ..= unindent().."until "..lua(t[2]) + return r + end, + -- If{ (lexpr block)+ block? } + If = (t) + local r = "" + local toClose = 0 -- blocks that need to be closed at the end of the if + local lets = search({ t[1] }, { "LetExpr" }) + if #lets > 0 then + r ..= "do"..indent() + toClose += 1 + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + end + r ..= "if "..lua(t[1]).." then"..indent()..lua(t[2])..unindent() + for i=3, #t-1, 2 do + lets = search({ t[i] }, { "LetExpr" }) + if #lets > 0 then + r ..= "else"..indent() + toClose += 1 + for _, l in ipairs(lets) do + r ..= lua(l, "Let")..newline() + end + else + r ..= "else" + end + r ..= "if "..lua(t[i]).." then"..indent()..lua(t[i+1])..unindent() + end + if #t % 2 == 1 then + r ..= "else"..indent()..lua(t[#t])..unindent() + end + r ..= "end" + for i=1, toClose do + r ..= unindent().."end" + end + return r + end, + -- Fornum{ ident expr expr expr? block } + Fornum = (t) + local r = "for "..lua(t[1]).." = "..lua(t[2])..", "..lua(t[3]) + if #t == 5 then + local hasContinue = any(t[5], { "Continue" }, loop) + r ..= ", "..lua(t[4]).." do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[5]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + else + local hasContinue = any(t[4], { "Continue" }, loop) + r ..= " do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= lua(t[4]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + end + end, + -- Forin{ {ident+} {expr+} block } + Forin = (t) + local destructured = {} + local hasContinue = any(t[3], { "Continue" }, loop) + local r = "for "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring").." in "..lua(t[2], "_lhs").." do"..indent() + if hasContinue then + r ..= CONTINUE_START() + end + r ..= DESTRUCTURING_ASSIGN(destructured, true)..lua(t[3]) + if hasContinue then + r ..= CONTINUE_STOP() + end + return r..unindent().."end" + end, + -- Local{ {attributeident+} {expr+}? } + Local = (t) + local destructured = {} + local r = "local "..push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") + if t[2][1] then + r ..= " = "..lua(t[2], "_lhs") + end + return r..DESTRUCTURING_ASSIGN(destructured) + end, + -- Let{ {ident+} {expr+}? } + Let = (t) + local destructured = {} + local nameList = push("destructuring", destructured)..lua(t[1], "_lhs")..pop("destructuring") + local r = "local "..nameList + if t[2][1] then + if all(t[2], { "Nil", "Dots", "Boolean", "Number", "String" }) then -- predeclaration doesn't matter here + r ..= " = "..lua(t[2], "_lhs") + else + r ..= newline()..nameList.." = "..lua(t[2], "_lhs") + end + end + return r..DESTRUCTURING_ASSIGN(destructured) + end, + -- Localrec{ {ident} {expr} } + Localrec = (t) + return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword") + end, + -- Goto{ } + Goto = (t) + return "goto "..lua(t, "Id") + end, + -- Label{ } + Label = (t) + return "::"..lua(t, "Id").."::" + end, + -- Return{ } + Return = (t) + local push = peek("push") + if push then + local r = "" + for _, val in ipairs(t) do + r ..= push.."[#"..push.."+1] = "..lua(val)..newline() + end + return r.."return "..UNPACK(push) + else + return "return "..lua(t, "_lhs") + end + end, + -- Push{ } + Push = (t) + local var = assert(peek("push"), "no context given for push") + r = "" + for i=1, #t-1, 1 do + r ..= var.."[#"..var.."+1] = "..lua(t[i])..newline() + end + if t[#t] then + if t[#t].tag == "Call" then + r ..= APPEND(var, lua(t[#t])) + else + r ..= var.."[#"..var.."+1] = "..lua(t[#t]) + end + end + return r + end, + -- Break + Break = () + return "break" + end, + -- Continue + Continue = () + return "goto "..var"continue" + end, + -- apply (below) + + -- expr -- + + -- Nil + Nil = () + return "nil" + end, + -- Dots + Dots = () + return "..." + end, + -- Boolean{ } + Boolean = (t) + return tostring(t[1]) + end, + -- Number{ } + Number = (t) + return tostring(t[1]) + end, + -- String{ } + String = (t) + return "%q":format(t[1]) + end, + -- Function{ { ( `ParPair{ Id expr } | `Id{ } )* `Dots? } block } + _functionWithoutKeyword = (t) + local r = "(" + local decl = {} + if t[1][1] then + if t[1][1].tag == "ParPair" then + local id = lua(t[1][1][1]) + indentLevel += 1 + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][1][2]).." end") + indentLevel -= 1 + r ..= id + else + r ..= lua(t[1][1]) + end + for i=2, #t[1], 1 do + if t[1][i].tag == "ParPair" then + local id = lua(t[1][i][1]) + indentLevel += 1 + table.insert(decl, "if "..id.." == nil then "..id.." = "..lua(t[1][i][2]).." end") + indentLevel -= 1 + r ..= ", " ..id + else + r ..= ", "..lua(t[1][i]) + end + end + end + r ..= ")"..indent() + for _, d in ipairs(decl) do + r ..= d..newline() + end + if t[2][#t[2]] and t[2][#t[2]].tag == "Push" then -- convert final push to return + t[2][#t[2]].tag = "Return" + end + local hasPush = any(t[2], { "Push" }, func) + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + else + push("push", false) -- no push here (make sure higher push doesn't affect us) + end + r ..= lua(t[2]) + if hasPush and (t[2][#t[2]] and t[2][#t[2]].tag ~= "Return") then -- add return only if needed + r ..= newline().."return "..UNPACK(var"push") + end + pop("push") + return r..unindent().."end" + end, + Function = (t) + return "function"..lua(t, "_functionWithoutKeyword") + end, + -- Table{ ( `Pair{ expr expr } | expr )* } + Pair = (t) + return "["..lua(t[1]).."] = "..lua(t[2]) + end, + Table = (t) + if #t == 0 then + return "{}" + elseif #t == 1 then + return "{ "..lua(t, "_lhs").." }" + else + return "{"..indent()..lua(t, "_lhs", nil, true)..unindent().."}" + end + end, + -- TableCompr{ block } + TableCompr = (t) + return push("push", "self").."(function()"..indent().."local self = {}"..newline()..lua(t[1])..newline().."return self"..unindent().."end)()"..pop("push") + end, + -- Op{ opid expr expr? } + Op = (t) + local r + if #t == 2 then + if type(tags._opid[t[1]]) == "string" then + r = tags._opid[t[1]].." "..lua(t[2]) + else + r = tags._opid[t[1]](t[2]) + end + else + if type(tags._opid[t[1]]) == "string" then + r = lua(t[2]).." "..tags._opid[t[1]].." "..lua(t[3]) + else + r = tags._opid[t[1]](t[2], t[3]) + end + end + return r + end, + -- Paren{ expr } + Paren = (t) + return "("..lua(t[1])..")" + end, + -- MethodStub{ expr expr } + MethodStub = (t) + return "(function()"..indent() .. + "local "..var"object".." = "..lua(t[1])..newline().. + "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. + "if "..var"method".." == nil then return nil end"..newline().. + "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. + "end)()" + end, + -- SafeMethodStub{ expr expr } + SafeMethodStub = (t) + return "(function()"..indent() .. + "local "..var"object".." = "..lua(t[1])..newline().. + "if "..var"object".." == nil then return nil end"..newline().. + "local "..var"method".." = "..var"object".."."..lua(t[2], "Id")..newline() .. + "if "..var"method".." == nil then return nil end"..newline().. + "return function(...) return "..var"method".."("..var"object"..", ...) end"..unindent().. + "end)()" + end, + -- statexpr (below) + -- apply (below) + -- lhs (below) + + -- lexpr -- + LetExpr = (t) + return lua(t[1][1]) + end, + + -- statexpr -- + _statexpr = (t, stat) + local hasPush = any(t, { "Push" }, func) + local r = "(function()"..indent() + if hasPush then + r ..= push("push", var"push").."local "..var"push".." = {}"..newline() + else + push("push", false) -- no push here (make sure higher push don't affect us) + end + r ..= lua(t, stat) + if hasPush then + r ..= newline().."return "..UNPACK(var"push") + end + pop("push") + r ..= unindent().."end)()" + return r + end, + -- DoExpr{ stat* } + DoExpr = (t) + if t[#t].tag == "Push" then -- convert final push to return + t[#t].tag = "Return" + end + return lua(t, "_statexpr", "Do") + end, + -- WhileExpr{ expr block } + WhileExpr = (t) + return lua(t, "_statexpr", "While") + end, + -- RepeatExpr{ block expr } + RepeatExpr = (t) + return lua(t, "_statexpr", "Repeat") + end, + -- IfExpr{ (expr block)+ block? } + IfExpr = (t) + for i=2, #t do -- convert final pushes to returns + local block = t[i] + if block[#block] and block[#block].tag == "Push" then + block[#block].tag = "Return" + end + end + return lua(t, "_statexpr", "If") + end, + -- FornumExpr{ ident expr expr expr? block } + FornumExpr = (t) + return lua(t, "_statexpr", "Fornum") + end, + -- ForinExpr{ {ident+} {expr+} block } + ForinExpr = (t) + return lua(t, "_statexpr", "Forin") + end, + + -- apply -- + + -- Call{ expr expr* } + Call = (t) + if t[1].tag == "String" or t[1].tag == "Table" then + return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" + elseif t[1].tag == "MethodStub" then -- method call + if t[1][1].tag == "String" or t[1][1].tag == "Table" then + return "("..lua(t[1][1]).."):"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" + else + return lua(t[1][1])..":"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" + end + else + return lua(t[1]).."("..lua(t, "_lhs", 2)..")" + end + end, + -- SafeCall{ expr expr* } + SafeCall = (t) + if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) + return lua(t, "SafeIndex") + else -- no side effects possible + return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."("..lua(t, "_lhs", 2)..") or nil)" + end + end, + + -- lhs -- + _lhs = (t, start=1, newlines) + local r + if t[start] then + r = lua(t[start]) + for i=start+1, #t, 1 do + r ..= ","..(newlines and newline() or " ")..lua(t[i]) + end + else + r = "" + end + return r + end, + -- Id{ } + Id = (t) + return t[1] + end, + -- AttributeId{ ? } + AttributeId = (t) + if t[2] then + return t[1] .. " <" .. t[2] .. ">" + else + return t[1] + end + end, + -- DestructuringId{ Id | Pair+ } + DestructuringId = (t) + if t.id then -- destructing already done before, use parent variable as id + return t.id + else + local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") + local vars = { id = tmp() } + for j=1, #t, 1 do + table.insert(vars, t[j]) + end + table.insert(d, vars) + t.id = vars.id + return vars.id + end + end, + -- Index{ expr expr } + Index = (t) + if t[1].tag == "String" or t[1].tag == "Table" then + return "("..lua(t[1])..")["..lua(t[2]).."]" + else + return lua(t[1]).."["..lua(t[2]).."]" + end + end, + -- SafeIndex{ expr expr } + SafeIndex = (t) + if t[1].tag ~= "Id" then -- side effect possible, only evaluate each expr once (or already in a safe context) + local l = {} -- list of immediately chained safeindex, from deepest to nearest (to simply generated code) + while t.tag == "SafeIndex" or t.tag == "SafeCall" do + table.insert(l, 1, t) + t = t[1] + end + local r = "(function()"..indent().."local "..var"safe".." = "..lua(l[1][1])..newline() -- base expr + for _, e in ipairs(l) do + r ..= "if "..var"safe".." == nil then return nil end"..newline() + if e.tag == "SafeIndex" then + r ..= var"safe".." = "..var"safe".."["..lua(e[2]).."]"..newline() + else + r ..= var"safe".." = "..var"safe".."("..lua(e, "_lhs", 2)..")"..newline() + end + end + r ..= "return "..var"safe"..unindent().."end)()" + return r + else -- no side effects possible + return "("..lua(t[1]).." ~= nil and "..lua(t[1]).."["..lua(t[2]).."] or nil)" + end + end, + + -- opid -- + _opid = { + add = "+", sub = "-", mul = "*", div = "/", + idiv = "//", mod = "%", pow = "^", concat = "..", + band = "&", bor = "|", bxor = "~", shl = "<<", shr = ">>", + eq = "==", ne = "~=", lt = "<", gt = ">", le = "<=", ge = ">=", + ["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not" + } + }, { + __index = (self, key) + error("don't know how to compile a "..tostring(key).." to "..targetName) + end + }) + + #placeholder("patch") + + local code = lua(ast)..newline() + return requireStr..code +end From cecb2aea031e5f03d63dbea20de3819c3ded63aa Mon Sep 17 00:00:00 2001 From: Reuh Date: Sat, 4 Jul 2020 23:42:51 +0200 Subject: [PATCH 16/52] Lua <5.4: Only error when the variable is declared with an attribute --- candran.lua | 50 +++++++++++++++++++++++++++++++--------------- compiler/lua53.can | 8 +++++++- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/candran.lua b/candran.lua index 5ff75d4..c9cb27a 100644 --- a/candran.lua +++ b/candran.lua @@ -1848,19 +1848,25 @@ end, -- ./compiler/lua54.can:813 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:10 -end -- ./compiler/lua53.can:10 -local lua53 = _() or lua53 -- ./compiler/lua53.can:14 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:15 -local function _() -- ./compiler/lua53.can:18 -local function _() -- ./compiler/lua53.can:20 -local function _() -- ./compiler/lua53.can:22 +return lua54 -- ./compiler/lua53.can:16 +end -- ./compiler/lua53.can:16 +local lua53 = _() or lua53 -- ./compiler/lua53.can:20 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:21 +local function _() -- ./compiler/lua53.can:24 +local function _() -- ./compiler/lua53.can:26 +local function _() -- ./compiler/lua53.can:28 local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 return function(code, ast, options) -- ./compiler/lua54.can:3 local lastInputPos = 1 -- ./compiler/lua54.can:5 @@ -2717,15 +2723,21 @@ end, -- ./compiler/lua54.can:813 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:10 -end -- ./compiler/lua53.can:10 -local lua53 = _() or lua53 -- ./compiler/lua53.can:14 +return lua54 -- ./compiler/lua53.can:16 +end -- ./compiler/lua53.can:16 +local lua53 = _() or lua53 -- ./compiler/lua53.can:20 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 @@ -3590,15 +3602,21 @@ end, -- ./compiler/lua54.can:813 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = nil -- ./compiler/lua53.can:4 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:10 -end -- ./compiler/lua53.can:10 -local lua53 = _() or lua53 -- ./compiler/lua53.can:14 +return lua54 -- ./compiler/lua53.can:16 +end -- ./compiler/lua53.can:16 +local lua53 = _() or lua53 -- ./compiler/lua53.can:20 return lua53 -- ./compiler/luajit.can:44 end -- ./compiler/luajit.can:44 local luajit = _() or luajit -- ./compiler/luajit.can:48 diff --git a/compiler/lua53.can b/compiler/lua53.can index 1bb0c53..ebee8dd 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -1,7 +1,13 @@ targetName = "Lua 5.3" -- Unsuported features -tags.AttributeId = nil +tags.AttributeId = (t) + if t[2] then + error("target does not support variable attributes") + else + return t[1] + end +end #local patch = output #output = "" From c8c35e93a8fc0e0ad6c3c16afb905bc5a793d41c Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 28 Aug 2020 23:41:33 +0200 Subject: [PATCH 17/52] Fix unpack/table.unpack rename in 5.3/5.4 --- candran.can | 2 + candran.lua | 451 ++++++++++++++++++++++++++-------------------------- 2 files changed, 228 insertions(+), 225 deletions(-) diff --git a/candran.can b/candran.can index 326ac0c..6546de9 100644 --- a/candran.can +++ b/candran.can @@ -11,6 +11,8 @@ #import("candran.can-parser.pp") #import("candran.can-parser.parser") +local unpack = unpack or table.unpack + local candran = { VERSION = "0.13.0" } diff --git a/candran.lua b/candran.lua index c9cb27a..2b51418 100644 --- a/candran.lua +++ b/candran.lua @@ -5355,250 +5355,251 @@ return parser -- ./candran/can-parser/parser.lua:777 end -- ./candran/can-parser/parser.lua:777 local parser = _() or parser -- ./candran/can-parser/parser.lua:781 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 -local candran = { ["VERSION"] = "0.13.0" } -- candran.can:15 -candran["default"] = { -- candran.can:19 -["target"] = "lua54", -- candran.can:20 -["indentation"] = "", -- candran.can:21 +local unpack = unpack or table["unpack"] -- candran.can:14 +local candran = { ["VERSION"] = "0.13.0" } -- candran.can:17 +candran["default"] = { -- candran.can:21 +["target"] = "lua54", -- candran.can:22 +["indentation"] = "", -- candran.can:23 ["newline"] = "\ -", -- candran.can:22 -["variablePrefix"] = "__CAN_", -- candran.can:23 -["mapLines"] = true, -- candran.can:24 -["chunkname"] = "nil", -- candran.can:25 -["rewriteErrors"] = true -- candran.can:26 -} -- candran.can:26 -if _VERSION == "Lua 5.1" then -- candran.can:30 -if package["loaded"]["jit"] then -- candran.can:31 -candran["default"]["target"] = "luajit" -- candran.can:32 -else -- candran.can:32 -candran["default"]["target"] = "lua51" -- candran.can:34 -end -- candran.can:34 -elseif _VERSION == "Lua 5.2" then -- candran.can:36 -candran["default"]["target"] = "lua51" -- candran.can:37 -elseif _VERSION == "Lua 5.3" then -- candran.can:38 - -- candran.can:40 -end -- candran.can:40 -candran["preprocess"] = function(input, options) -- candran.can:48 -if options == nil then options = {} end -- candran.can:48 -options = util["merge"](candran["default"], options) -- candran.can:49 -local preprocessor = "" -- candran.can:52 -local i = 0 -- candran.can:53 -local inLongString = false -- candran.can:54 -local inComment = false -- candran.can:55 +", -- candran.can:24 +["variablePrefix"] = "__CAN_", -- candran.can:25 +["mapLines"] = true, -- candran.can:26 +["chunkname"] = "nil", -- candran.can:27 +["rewriteErrors"] = true -- candran.can:28 +} -- candran.can:28 +if _VERSION == "Lua 5.1" then -- candran.can:32 +if package["loaded"]["jit"] then -- candran.can:33 +candran["default"]["target"] = "luajit" -- candran.can:34 +else -- candran.can:34 +candran["default"]["target"] = "lua51" -- candran.can:36 +end -- candran.can:36 +elseif _VERSION == "Lua 5.2" then -- candran.can:38 +candran["default"]["target"] = "lua51" -- candran.can:39 +elseif _VERSION == "Lua 5.3" then -- candran.can:40 + -- candran.can:42 +end -- candran.can:42 +candran["preprocess"] = function(input, options) -- candran.can:50 +if options == nil then options = {} end -- candran.can:50 +options = util["merge"](candran["default"], options) -- candran.can:51 +local preprocessor = "" -- candran.can:54 +local i = 0 -- candran.can:55 +local inLongString = false -- candran.can:56 +local inComment = false -- candran.can:57 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:56 -i = i + (1) -- candran.can:57 -if inComment then -- candran.can:59 -inComment = not line:match("%]%]") -- candran.can:60 -elseif inLongString then -- candran.can:61 -inLongString = not line:match("%]%]") -- candran.can:62 -else -- candran.can:62 -if line:match("[^%-]%[%[") then -- candran.can:64 -inLongString = true -- candran.can:65 -elseif line:match("%-%-%[%[") then -- candran.can:66 -inComment = true -- candran.can:67 -end -- candran.can:67 -end -- candran.can:67 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:70 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:71 -else -- candran.can:71 -local l = line:sub(1, - 2) -- candran.can:73 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:74 +)") do -- candran.can:58 +i = i + (1) -- candran.can:59 +if inComment then -- candran.can:61 +inComment = not line:match("%]%]") -- candran.can:62 +elseif inLongString then -- candran.can:63 +inLongString = not line:match("%]%]") -- candran.can:64 +else -- candran.can:64 +if line:match("[^%-]%[%[") then -- candran.can:66 +inLongString = true -- candran.can:67 +elseif line:match("%-%-%[%[") then -- candran.can:68 +inComment = true -- candran.can:69 +end -- candran.can:69 +end -- candran.can:69 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:72 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:73 +else -- candran.can:73 +local l = line:sub(1, - 2) -- candran.can:75 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:76 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:75 -else -- candran.can:75 -preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ ") -- candran.can:77 -end -- candran.can:77 -end -- candran.can:77 -end -- candran.can:77 -preprocessor = preprocessor .. ("return output") -- candran.can:81 -local env = util["merge"](_G, options) -- candran.can:84 -env["candran"] = candran -- candran.can:86 -env["output"] = "" -- candran.can:88 -env["import"] = function(modpath, margs) -- candran.can:95 -if margs == nil then margs = {} end -- candran.can:95 -local filepath = assert(util["search"](modpath, { -- candran.can:96 -"can", -- candran.can:96 -"lua" -- candran.can:96 -}), "No module named \"" .. modpath .. "\"") -- candran.can:96 -local f = io["open"](filepath) -- candran.can:99 -if not f then -- candran.can:100 -error("can't open the module file to import") -- candran.can:100 -end -- candran.can:100 -margs = util["merge"](options, { -- candran.can:102 -["chunkname"] = filepath, -- candran.can:102 -["loadLocal"] = true, -- candran.can:102 -["loadPackage"] = true -- candran.can:102 -}, margs) -- candran.can:102 -local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:103 -f:close() -- candran.can:104 -local modname = modpath:match("[^%.]+$") -- candran.can:107 +else -- candran.can:77 +preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ +") -- candran.can:79 +end -- candran.can:79 +end -- candran.can:79 +end -- candran.can:79 +preprocessor = preprocessor .. ("return output") -- candran.can:83 +local env = util["merge"](_G, options) -- candran.can:86 +env["candran"] = candran -- candran.can:88 +env["output"] = "" -- candran.can:90 +env["import"] = function(modpath, margs) -- candran.can:97 +if margs == nil then margs = {} end -- candran.can:97 +local filepath = assert(util["search"](modpath, { -- candran.can:98 +"can", -- candran.can:98 +"lua" -- candran.can:98 +}), "No module named \"" .. modpath .. "\"") -- candran.can:98 +local f = io["open"](filepath) -- candran.can:101 +if not f then -- candran.can:102 +error("can't open the module file to import") -- candran.can:102 +end -- candran.can:102 +margs = util["merge"](options, { -- candran.can:104 +["chunkname"] = filepath, -- candran.can:104 +["loadLocal"] = true, -- candran.can:104 +["loadPackage"] = true -- candran.can:104 +}, margs) -- candran.can:104 +local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:105 +f:close() -- candran.can:106 +local modname = modpath:match("[^%.]+$") -- candran.can:109 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:116 -end -- candran.can:116 -env["include"] = function(file) -- candran.can:121 -local f = io["open"](file) -- candran.can:122 -if not f then -- candran.can:123 -error("can't open the file " .. file .. " to include") -- candran.can:123 -end -- candran.can:123 -env["write"](f:read("*a")) -- candran.can:124 -f:close() -- candran.can:125 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:118 +end -- candran.can:118 +env["include"] = function(file) -- candran.can:123 +local f = io["open"](file) -- candran.can:124 +if not f then -- candran.can:125 +error("can't open the file " .. file .. " to include") -- candran.can:125 end -- candran.can:125 -env["write"] = function(...) -- candran.can:129 +env["write"](f:read("*a")) -- candran.can:126 +f:close() -- candran.can:127 +end -- candran.can:127 +env["write"] = function(...) -- candran.can:131 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:130 -end -- candran.can:130 -env["placeholder"] = function(name) -- candran.can:134 -if env[name] then -- candran.can:135 -env["write"](env[name]) -- candran.can:136 -end -- candran.can:136 -end -- candran.can:136 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:141 -if not preprocess then -- candran.can:142 -return nil, "in preprocessor: " .. err -- candran.can:143 -end -- candran.can:143 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:146 -if not preprocess then -- candran.can:147 -return nil, "in preprocessor: " .. err -- candran.can:148 -end -- candran.can:148 -local success, output = pcall(preprocess) -- candran.can:152 -if not success then -- candran.can:153 -return nil, "in preprocessor: " .. output -- candran.can:154 -end -- candran.can:154 -return output -- candran.can:157 -end -- candran.can:157 -candran["compile"] = function(input, options) -- candran.can:166 -if options == nil then options = {} end -- candran.can:166 -options = util["merge"](candran["default"], options) -- candran.can:167 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:169 -if not ast then -- candran.can:171 -return nil, errmsg -- candran.can:172 -end -- candran.can:172 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:175 -end -- candran.can:175 -candran["make"] = function(code, options) -- candran.can:184 -local r, err = candran["preprocess"](code, options) -- candran.can:185 -if r then -- candran.can:186 -r, err = candran["compile"](r, options) -- candran.can:187 +") -- candran.can:132 +end -- candran.can:132 +env["placeholder"] = function(name) -- candran.can:136 +if env[name] then -- candran.can:137 +env["write"](env[name]) -- candran.can:138 +end -- candran.can:138 +end -- candran.can:138 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:143 +if not preprocess then -- candran.can:144 +return nil, "in preprocessor: " .. err -- candran.can:145 +end -- candran.can:145 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:148 +if not preprocess then -- candran.can:149 +return nil, "in preprocessor: " .. err -- candran.can:150 +end -- candran.can:150 +local success, output = pcall(preprocess) -- candran.can:154 +if not success then -- candran.can:155 +return nil, "in preprocessor: " .. output -- candran.can:156 +end -- candran.can:156 +return output -- candran.can:159 +end -- candran.can:159 +candran["compile"] = function(input, options) -- candran.can:168 +if options == nil then options = {} end -- candran.can:168 +options = util["merge"](candran["default"], options) -- candran.can:169 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:171 +if not ast then -- candran.can:173 +return nil, errmsg -- candran.can:174 +end -- candran.can:174 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:177 +end -- candran.can:177 +candran["make"] = function(code, options) -- candran.can:186 +local r, err = candran["preprocess"](code, options) -- candran.can:187 if r then -- candran.can:188 -return r -- candran.can:189 -end -- candran.can:189 -end -- candran.can:189 -return r, err -- candran.can:192 -end -- candran.can:192 -local errorRewritingActive = false -- candran.can:195 -local codeCache = {} -- candran.can:196 -candran["loadfile"] = function(filepath, env, options) -- candran.can:199 -local f, err = io["open"](filepath) -- candran.can:200 -if not f then -- candran.can:201 -return nil, ("cannot open %s"):format(err) -- candran.can:202 -end -- candran.can:202 -local content = f:read("*a") -- candran.can:204 -f:close() -- candran.can:205 -return candran["load"](content, filepath, env, options) -- candran.can:207 -end -- candran.can:207 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:212 -if options == nil then options = {} end -- candran.can:212 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:213 -local code, err = candran["make"](chunk, options) -- candran.can:215 -if not code then -- candran.can:216 -return code, err -- candran.can:217 -end -- candran.can:217 -codeCache[options["chunkname"]] = code -- candran.can:220 -local f, err = util["load"](code, options["chunkname"], env) -- candran.can:221 -if f == nil then -- candran.can:226 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:227 -end -- candran.can:227 -if options["rewriteErrors"] == false then -- candran.can:230 -return f -- candran.can:231 -else -- candran.can:231 -return function(...) -- candran.can:233 -local params = { ... } -- candran.can:234 -if not errorRewritingActive then -- candran.can:235 -errorRewritingActive = true -- candran.can:236 -local t = { xpcall(function() -- candran.can:237 -return f(unpack(params)) -- candran.can:237 -end, candran["messageHandler"]) } -- candran.can:237 -errorRewritingActive = false -- candran.can:238 -if t[1] == false then -- candran.can:239 -error(t[2], 0) -- candran.can:240 -end -- candran.can:240 -return unpack(t, 2) -- candran.can:242 -else -- candran.can:242 -return f(...) -- candran.can:244 -end -- candran.can:244 -end -- candran.can:244 -end -- candran.can:244 -end -- candran.can:244 -candran["dofile"] = function(filename, options) -- candran.can:252 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:253 -if f == nil then -- candran.can:255 -error(err) -- candran.can:256 -else -- candran.can:256 -return f() -- candran.can:258 -end -- candran.can:258 -end -- candran.can:258 -candran["messageHandler"] = function(message) -- candran.can:264 +r, err = candran["compile"](r, options) -- candran.can:189 +if r then -- candran.can:190 +return r -- candran.can:191 +end -- candran.can:191 +end -- candran.can:191 +return r, err -- candran.can:194 +end -- candran.can:194 +local errorRewritingActive = false -- candran.can:197 +local codeCache = {} -- candran.can:198 +candran["loadfile"] = function(filepath, env, options) -- candran.can:201 +local f, err = io["open"](filepath) -- candran.can:202 +if not f then -- candran.can:203 +return nil, ("cannot open %s"):format(err) -- candran.can:204 +end -- candran.can:204 +local content = f:read("*a") -- candran.can:206 +f:close() -- candran.can:207 +return candran["load"](content, filepath, env, options) -- candran.can:209 +end -- candran.can:209 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:214 +if options == nil then options = {} end -- candran.can:214 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:215 +local code, err = candran["make"](chunk, options) -- candran.can:217 +if not code then -- candran.can:218 +return code, err -- candran.can:219 +end -- candran.can:219 +codeCache[options["chunkname"]] = code -- candran.can:222 +local f, err = util["load"](code, options["chunkname"], env) -- candran.can:223 +if f == nil then -- candran.can:228 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:229 +end -- candran.can:229 +if options["rewriteErrors"] == false then -- candran.can:232 +return f -- candran.can:233 +else -- candran.can:233 +return function(...) -- candran.can:235 +local params = { ... } -- candran.can:236 +if not errorRewritingActive then -- candran.can:237 +errorRewritingActive = true -- candran.can:238 +local t = { xpcall(function() -- candran.can:239 +return f(unpack(params)) -- candran.can:239 +end, candran["messageHandler"]) } -- candran.can:239 +errorRewritingActive = false -- candran.can:240 +if t[1] == false then -- candran.can:241 +error(t[2], 0) -- candran.can:242 +end -- candran.can:242 +return unpack(t, 2) -- candran.can:244 +else -- candran.can:244 +return f(...) -- candran.can:246 +end -- candran.can:246 +end -- candran.can:246 +end -- candran.can:246 +end -- candran.can:246 +candran["dofile"] = function(filename, options) -- candran.can:254 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:255 +if f == nil then -- candran.can:257 +error(err) -- candran.can:258 +else -- candran.can:258 +return f() -- candran.can:260 +end -- candran.can:260 +end -- candran.can:260 +candran["messageHandler"] = function(message) -- candran.can:266 return debug["traceback"](message, 2):gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:265 -line = tonumber(line) -- candran.can:266 -local originalFile -- candran.can:268 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:269 -if strName then -- candran.can:270 -if codeCache[strName] then -- candran.can:271 -originalFile = codeCache[strName] -- candran.can:272 -source = strName -- candran.can:273 -end -- candran.can:273 -else -- candran.can:273 -local fi = io["open"](source, "r") -- candran.can:276 -if fi then -- candran.can:277 -originalFile = fi:read("*a") -- candran.can:278 -fi:close() -- candran.can:279 -end -- candran.can:279 -end -- candran.can:279 -if originalFile then -- candran.can:283 -local i = 0 -- candran.can:284 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:267 +line = tonumber(line) -- candran.can:268 +local originalFile -- candran.can:270 +local strName = source:match("%[string \"(.-)\"%]") -- candran.can:271 +if strName then -- candran.can:272 +if codeCache[strName] then -- candran.can:273 +originalFile = codeCache[strName] -- candran.can:274 +source = strName -- candran.can:275 +end -- candran.can:275 +else -- candran.can:275 +local fi = io["open"](source, "r") -- candran.can:278 +if fi then -- candran.can:279 +originalFile = fi:read("*a") -- candran.can:280 +fi:close() -- candran.can:281 +end -- candran.can:281 +end -- candran.can:281 +if originalFile then -- candran.can:285 +local i = 0 -- candran.can:286 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:285 -i = i + 1 -- candran.can:286 -if i == line then -- candran.can:287 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:288 -if lineMap then -- candran.can:289 -if extSource ~= source then -- candran.can:290 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:291 -else -- candran.can:291 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:293 -end -- candran.can:293 -end -- candran.can:293 -break -- candran.can:296 -end -- candran.can:296 -end -- candran.can:296 -end -- candran.can:296 -end) -- candran.can:296 -end -- candran.can:296 -candran["searcher"] = function(modpath) -- candran.can:304 -local filepath = util["search"](modpath, { "can" }) -- candran.can:305 -if not filepath then -- candran.can:306 +") do -- candran.can:287 +i = i + 1 -- candran.can:288 +if i == line then -- candran.can:289 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:290 +if lineMap then -- candran.can:291 +if extSource ~= source then -- candran.can:292 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:293 +else -- candran.can:293 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:295 +end -- candran.can:295 +end -- candran.can:295 +break -- candran.can:298 +end -- candran.can:298 +end -- candran.can:298 +end -- candran.can:298 +end) -- candran.can:298 +end -- candran.can:298 +candran["searcher"] = function(modpath) -- candran.can:306 +local filepath = util["search"](modpath, { "can" }) -- candran.can:307 +if not filepath then -- candran.can:308 return "\ -\9no candran file in package.path" -- candran.can:307 -end -- candran.can:307 -return candran["loadfile"](filepath) -- candran.can:309 +\9no candran file in package.path" -- candran.can:309 end -- candran.can:309 -candran["setup"] = function() -- candran.can:313 -if _VERSION == "Lua 5.1" then -- candran.can:314 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:315 -else -- candran.can:315 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:317 -end -- candran.can:317 -return candran -- candran.can:319 +return candran["loadfile"](filepath) -- candran.can:311 +end -- candran.can:311 +candran["setup"] = function() -- candran.can:315 +if _VERSION == "Lua 5.1" then -- candran.can:316 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:317 +else -- candran.can:317 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:319 end -- candran.can:319 -return candran -- candran.can:322 +return candran -- candran.can:321 +end -- candran.can:321 +return candran -- candran.can:324 From c8aa4f2a0874c7f97ce5e4db8c8bfe2d8be814f2 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 16:24:26 +0100 Subject: [PATCH 18/52] Improve error reporting in candran.searcher --- candran.can | 17 +++++++++++++---- candran.lua | 37 +++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/candran.can b/candran.can index 6546de9..8a05216 100644 --- a/candran.can +++ b/candran.can @@ -14,7 +14,7 @@ local unpack = unpack or table.unpack local candran = { - VERSION = "0.13.0" + VERSION = "0.13.1" } --- Default options. @@ -38,7 +38,7 @@ if _VERSION == "Lua 5.1" then elseif _VERSION == "Lua 5.2" then candran.default.target = "lua51" elseif _VERSION == "Lua 5.3" then - --candran.default.target = "lua53" + candran.default.target = "lua53" end --- Run the preprocessor @@ -306,9 +306,18 @@ end function candran.searcher(modpath) local filepath = util.search(modpath, {"can"}) if not filepath then - return "\n\tno candran file in package.path" + if _VERSION == "Lua 5.4" then + return "no candran file in package.path" + else + return "\n\tno candran file in package.path" + end + end + local r, s = candran.loadfile(filepath) + if r then + return r + else + return s end - return candran.loadfile(filepath) end --- Register the Candran package searcher. diff --git a/candran.lua b/candran.lua index 2b51418..14a39ab 100644 --- a/candran.lua +++ b/candran.lua @@ -5356,7 +5356,7 @@ end -- ./candran/can-parser/parser.lua:777 local parser = _() or parser -- ./candran/can-parser/parser.lua:781 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 local unpack = unpack or table["unpack"] -- candran.can:14 -local candran = { ["VERSION"] = "0.13.0" } -- candran.can:17 +local candran = { ["VERSION"] = "0.13.1" } -- candran.can:17 candran["default"] = { -- candran.can:21 ["target"] = "lua54", -- candran.can:22 ["indentation"] = "", -- candran.can:23 @@ -5376,8 +5376,8 @@ end -- candran.can:36 elseif _VERSION == "Lua 5.2" then -- candran.can:38 candran["default"]["target"] = "lua51" -- candran.can:39 elseif _VERSION == "Lua 5.3" then -- candran.can:40 - -- candran.can:42 -end -- candran.can:42 +candran["default"]["target"] = "lua53" -- candran.can:41 +end -- candran.can:41 candran["preprocess"] = function(input, options) -- candran.can:50 if options == nil then options = {} end -- candran.can:50 options = util["merge"](candran["default"], options) -- candran.can:51 @@ -5589,17 +5589,26 @@ end -- candran.can:298 candran["searcher"] = function(modpath) -- candran.can:306 local filepath = util["search"](modpath, { "can" }) -- candran.can:307 if not filepath then -- candran.can:308 +if _VERSION == "Lua 5.4" then -- candran.can:309 +return "no candran file in package.path" -- candran.can:310 +else -- candran.can:310 return "\ -\9no candran file in package.path" -- candran.can:309 -end -- candran.can:309 -return candran["loadfile"](filepath) -- candran.can:311 -end -- candran.can:311 -candran["setup"] = function() -- candran.can:315 -if _VERSION == "Lua 5.1" then -- candran.can:316 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:317 +\9no candran file in package.path" -- candran.can:312 +end -- candran.can:312 +end -- candran.can:312 +local r, s = candran["loadfile"](filepath) -- candran.can:315 +if r then -- candran.can:316 +return r -- candran.can:317 else -- candran.can:317 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:319 +return s -- candran.can:319 end -- candran.can:319 -return candran -- candran.can:321 -end -- candran.can:321 -return candran -- candran.can:324 +end -- candran.can:319 +candran["setup"] = function() -- candran.can:324 +if _VERSION == "Lua 5.1" then -- candran.can:325 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:326 +else -- candran.can:326 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:328 +end -- candran.can:328 +return candran -- candran.can:330 +end -- candran.can:330 +return candran -- candran.can:333 From bf4cadc34911b298d1e3d449c267f42541bf3835 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 17:24:36 +0100 Subject: [PATCH 19/52] Colorize tests output and fix Lua5.1 compatibility --- test/test.lua | 60 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/test/test.lua b/test/test.lua index 62ef409..76bbcb9 100644 --- a/test/test.lua +++ b/test/test.lua @@ -4,6 +4,37 @@ candran.default.mapLines = false local load = require("candran.util").load +-- Text formatting +local colors = { + black = 30, + red = 31, + green = 32, + yellow = 33, + blue = 34, + purple = 35, + cyan = 36, + white = 37, + + bgBlack = 40, + bgRed = 41, + bgGreen = 42, + bgYellow = 43, + bgBlue = 44, + bgPurple = 45, + bgCyan = 46, + bgWhite = 47, + + bold = 1, + underline = 4 +} +local function c(text, ...) + local codes = {} + for _, color in ipairs{...} do + table.insert(codes, colors[color]) + end + return ("\027[%sm%s\027[0m"):format(table.concat(codes, ";"), text) +end + -- test helper local results = {} -- tests result local function test(name, candranCode, expectedResult, options) @@ -18,7 +49,7 @@ local function test(name, candranCode, expectedResult, options) local success, code = pcall(function() return assert(candran.make(candranCode, options)) end) if not success then self.result = "error" - self.message = "/!\\ error while making code:\n"..code + self.message = c("/!\\ error while making code:\n", "bold", "red")..c(code, "red") return end @@ -28,7 +59,7 @@ local function test(name, candranCode, expectedResult, options) local success, func = pcall(load, code, nil, env) if not success then self.result = "error" - self.message = "/!\\ error while loading code:\n"..func.."\ngenerated code:\n"..code + self.message = c("/!\\ error while loading code:\n"..func.."\ngenerated code:\n", "bold", "red")..c(code, "red") return end @@ -36,14 +67,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.."\ngenerated code:\n"..code + self.message = c("/!\\ error while running code:\n"..output.."\ngenerated code:\n", "bold", "red")..c(code, "red") return end -- check result if output ~= expectedResult then self.result = "fail" - self.message = "/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult).."; generated code:\n"..code + self.message = c("/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult).."; generated code:\n", "bold", "purple")..c(code, "purple") return else self.result = "success" @@ -105,21 +136,18 @@ test("preprocessor options", [[ return true ]], true, { foo = "sky" }) -test("preprocessor long comment", [[ ---[[ +test("preprocessor long comment", "--[[\n"..[[ #error("preprocessor should ignore long comments") ]].."]]"..[[ return true ]], true) test("preprocessor long comment in long string", [[ -a=]].."[["..[[ ---[[ +a=]].."[[--[[\n"..[[ #error("preprocessor should ignore long strings") ]].."]]"..[[ return a -]], [[ ---[[ +]], "--[[\n"..[[ #error("preprocessor should ignore long strings") ]]) @@ -375,9 +403,9 @@ test("short anonymous method parsing edge cases", [[ if a() then h() end local function f (...) if select('#', ...) == 1 then - return (...) + return (...) else - return "***" + return "***" end end return f(x) @@ -585,6 +613,7 @@ test("table comprehension associative/self", [[ return a[1] and a[10] ]], true) test("table comprehension variable length", [[ + local unpack = table.unpack or unpack t1 = {"hey", "hop"} t2 = {"foo", "bar"} return table.concat([push unpack(t1); push unpack(t2)]) @@ -1024,7 +1053,8 @@ for name, t in pairs(results) do end -- print final results -for name, count in pairs(resultCounter) do - print(count.." "..name.." (" .. math.floor((count / testCounter * 100)*100)/100 .. "%)") +for _, name in ipairs{{"error", "red"}, {"fail", "purple"}, {"success", "green"}} do + local count = resultCounter[name[1]] or 0 + print(c(count, "bold", name[2])..c(" "..name[1].." (" .. math.floor((count / testCounter * 100)*100)/100 .. "%)", name[2])) end -print(testCounter.." total") +print(c(testCounter.." total", "bold")) From 7e4b46ba7df35c2e5b20634d62dab052e62a55f9 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 17:25:28 +0100 Subject: [PATCH 20/52] Add Lua 5.2 target --- candran.can | 3 +- candran.lua | 1576 +++++++++++++++++++++++++++++++++++-------- compiler/lua51.can | 10 +- compiler/lua52.can | 35 + compiler/lua53.can | 4 +- compiler/luajit.can | 10 +- 6 files changed, 1359 insertions(+), 279 deletions(-) create mode 100644 compiler/lua52.can diff --git a/candran.can b/candran.can index 8a05216..a80cf91 100644 --- a/candran.can +++ b/candran.can @@ -3,6 +3,7 @@ #import("compiler.lua54") #import("compiler.lua53") +#import("compiler.lua52") #import("compiler.luajit") #import("compiler.lua51") @@ -36,7 +37,7 @@ if _VERSION == "Lua 5.1" then candran.default.target = "lua51" end elseif _VERSION == "Lua 5.2" then - candran.default.target = "lua51" + candran.default.target = "lua52" elseif _VERSION == "Lua 5.3" then candran.default.target = "lua53" end diff --git a/candran.lua b/candran.lua index 14a39ab..28e491e 100644 --- a/candran.lua +++ b/candran.lua @@ -1850,7 +1850,7 @@ end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 -error("target does not support variable attributes") -- ./compiler/lua53.can:6 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 @@ -1860,13 +1860,13 @@ return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:16 -end -- ./compiler/lua53.can:16 -local lua53 = _() or lua53 -- ./compiler/lua53.can:20 -package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:21 -local function _() -- ./compiler/lua53.can:24 +return lua54 -- ./compiler/lua53.can:18 +end -- ./compiler/lua53.can:18 +local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:23 local function _() -- ./compiler/lua53.can:26 local function _() -- ./compiler/lua53.can:28 +local function _() -- ./compiler/lua53.can:30 local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 return function(code, ast, options) -- ./compiler/lua54.can:3 local lastInputPos = 1 -- ./compiler/lua54.can:5 @@ -2725,27 +2725,988 @@ end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 -error("target does not support variable attributes") -- ./compiler/lua53.can:6 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:16 -end -- ./compiler/lua53.can:16 -local lua53 = _() or lua53 -- ./compiler/lua53.can:20 -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 +return lua54 -- ./compiler/lua53.can:18 +end -- ./compiler/lua53.can:18 +local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +return lua53 -- ./compiler/lua52.can:35 +end -- ./compiler/lua52.can:35 +local lua52 = _() or lua52 -- ./compiler/lua52.can:39 +package["loaded"]["compiler.lua52"] = lua52 or true -- ./compiler/lua52.can:40 +local function _() -- ./compiler/lua52.can:43 +local function _() -- ./compiler/lua52.can:45 +local function _() -- ./compiler/lua52.can:47 +local function _() -- ./compiler/lua52.can:49 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 +return function(code, ast, options) -- ./compiler/lua54.can:3 +local lastInputPos = 1 -- ./compiler/lua54.can:5 +local prevLinePos = 1 -- ./compiler/lua54.can:6 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 +local lastLine = 1 -- ./compiler/lua54.can:8 +local indentLevel = 0 -- ./compiler/lua54.can:11 +local function newline() -- ./compiler/lua54.can:13 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 +if options["mapLines"] then -- ./compiler/lua54.can:15 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local source, line = sub:sub(1, sub:find("\ +")):match(".*%-%- (.-)%:(%d+)\ +") -- ./compiler/lua54.can:17 +if source and line then -- ./compiler/lua54.can:19 +lastSource = source -- ./compiler/lua54.can:20 +lastLine = tonumber(line) -- ./compiler/lua54.can:21 +else -- ./compiler/lua54.can:21 +for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ +") do -- ./compiler/lua54.can:23 +lastLine = lastLine + (1) -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +end -- ./compiler/lua54.can:24 +prevLinePos = lastInputPos -- ./compiler/lua54.can:28 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 +end -- ./compiler/lua54.can:30 +return r -- ./compiler/lua54.can:32 +end -- ./compiler/lua54.can:32 +local function indent() -- ./compiler/lua54.can:35 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 +return newline() -- ./compiler/lua54.can:37 +end -- ./compiler/lua54.can:37 +local function unindent() -- ./compiler/lua54.can:40 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 +return newline() -- ./compiler/lua54.can:42 +end -- ./compiler/lua54.can:42 +local states = { -- ./compiler/lua54.can:47 +["push"] = {}, -- ./compiler/lua54.can:48 +["destructuring"] = {}, -- ./compiler/lua54.can:49 +["scope"] = {} -- ./compiler/lua54.can:50 +} -- ./compiler/lua54.can:50 +local function push(name, state) -- ./compiler/lua54.can:53 +table["insert"](states[name], state) -- ./compiler/lua54.can:54 +return "" -- ./compiler/lua54.can:55 +end -- ./compiler/lua54.can:55 +local function pop(name) -- ./compiler/lua54.can:58 +table["remove"](states[name]) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function set(name, state) -- ./compiler/lua54.can:63 +states[name][# states[name]] = state -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function peek(name) -- ./compiler/lua54.can:68 +return states[name][# states[name]] -- ./compiler/lua54.can:69 +end -- ./compiler/lua54.can:69 +local function var(name) -- ./compiler/lua54.can:74 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 +end -- ./compiler/lua54.can:75 +local function tmp() -- ./compiler/lua54.can:79 +local scope = peek("scope") -- ./compiler/lua54.can:80 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 +table["insert"](scope, var) -- ./compiler/lua54.can:82 +return var -- ./compiler/lua54.can:83 +end -- ./compiler/lua54.can:83 +local required = {} -- ./compiler/lua54.can:87 +local requireStr = "" -- ./compiler/lua54.can:88 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 +if not required[req] then -- ./compiler/lua54.can:92 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 +required[req] = true -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +end -- ./compiler/lua54.can:94 +local loop = { -- ./compiler/lua54.can:99 +"While", -- ./compiler/lua54.can:99 +"Repeat", -- ./compiler/lua54.can:99 +"Fornum", -- ./compiler/lua54.can:99 +"Forin", -- ./compiler/lua54.can:99 +"WhileExpr", -- ./compiler/lua54.can:99 +"RepeatExpr", -- ./compiler/lua54.can:99 +"FornumExpr", -- ./compiler/lua54.can:99 +"ForinExpr" -- ./compiler/lua54.can:99 +} -- ./compiler/lua54.can:99 +local func = { -- ./compiler/lua54.can:100 +"Function", -- ./compiler/lua54.can:100 +"TableCompr", -- ./compiler/lua54.can:100 +"DoExpr", -- ./compiler/lua54.can:100 +"WhileExpr", -- ./compiler/lua54.can:100 +"RepeatExpr", -- ./compiler/lua54.can:100 +"IfExpr", -- ./compiler/lua54.can:100 +"FornumExpr", -- ./compiler/lua54.can:100 +"ForinExpr" -- ./compiler/lua54.can:100 +} -- ./compiler/lua54.can:100 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 +local tagsCheck = {} -- ./compiler/lua54.can:105 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 +tagsCheck[tag] = true -- ./compiler/lua54.can:107 +end -- ./compiler/lua54.can:107 +local nofollowCheck = {} -- ./compiler/lua54.can:109 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 +nofollowCheck[tag] = true -- ./compiler/lua54.can:111 +end -- ./compiler/lua54.can:111 +for _, node in ipairs(list) do -- ./compiler/lua54.can:113 +if type(node) == "table" then -- ./compiler/lua54.can:114 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 +return node -- ./compiler/lua54.can:116 +end -- ./compiler/lua54.can:116 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 +if r then -- ./compiler/lua54.can:120 +return r -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +end -- ./compiler/lua54.can:120 +return nil -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 +local tagsCheck = {} -- ./compiler/lua54.can:130 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 +tagsCheck[tag] = true -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local nofollowCheck = {} -- ./compiler/lua54.can:134 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 +nofollowCheck[tag] = true -- ./compiler/lua54.can:136 +end -- ./compiler/lua54.can:136 +local found = {} -- ./compiler/lua54.can:138 +for _, node in ipairs(list) do -- ./compiler/lua54.can:139 +if type(node) == "table" then -- ./compiler/lua54.can:140 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 +table["insert"](found, n) -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +end -- ./compiler/lua54.can:143 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 +table["insert"](found, node) -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +end -- ./compiler/lua54.can:147 +return found -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +local function all(list, tags) -- ./compiler/lua54.can:155 +for _, node in ipairs(list) do -- ./compiler/lua54.can:156 +local ok = false -- ./compiler/lua54.can:157 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 +if node["tag"] == tag then -- ./compiler/lua54.can:159 +ok = true -- ./compiler/lua54.can:160 +break -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +end -- ./compiler/lua54.can:161 +if not ok then -- ./compiler/lua54.can:164 +return false -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +end -- ./compiler/lua54.can:165 +return true -- ./compiler/lua54.can:168 +end -- ./compiler/lua54.can:168 +local tags -- ./compiler/lua54.can:172 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 +end -- ./compiler/lua54.can:178 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 +end -- ./compiler/lua54.can:183 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local CONTINUE_START = function() -- ./compiler/lua54.can:188 +return "do" .. indent() -- ./compiler/lua54.can:189 +end -- ./compiler/lua54.can:189 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +end -- ./compiler/lua54.can:192 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 +local vars = {} -- ./compiler/lua54.can:195 +local values = {} -- ./compiler/lua54.can:196 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 +for _, v in ipairs(list) do -- ./compiler/lua54.can:198 +local var, val -- ./compiler/lua54.can:199 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 +var = v -- ./compiler/lua54.can:201 +val = { -- ./compiler/lua54.can:202 +["tag"] = "Index", -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "Id", -- ./compiler/lua54.can:202 +list["id"] -- ./compiler/lua54.can:202 +}, -- ./compiler/lua54.can:202 +{ -- ./compiler/lua54.can:202 +["tag"] = "String", -- ./compiler/lua54.can:202 +v[1] -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +} -- ./compiler/lua54.can:202 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 +var = v[2] -- ./compiler/lua54.can:204 +val = { -- ./compiler/lua54.can:205 +["tag"] = "Index", -- ./compiler/lua54.can:205 +{ -- ./compiler/lua54.can:205 +["tag"] = "Id", -- ./compiler/lua54.can:205 +list["id"] -- ./compiler/lua54.can:205 +}, -- ./compiler/lua54.can:205 +v[1] -- ./compiler/lua54.can:205 +} -- ./compiler/lua54.can:205 +else -- ./compiler/lua54.can:205 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 +end -- ./compiler/lua54.can:207 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["rightOp"], -- ./compiler/lua54.can:210 +var, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Op", -- ./compiler/lua54.can:210 +destructured["leftOp"], -- ./compiler/lua54.can:210 +val, -- ./compiler/lua54.can:210 +var -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 +val = { -- ./compiler/lua54.can:212 +["tag"] = "Op", -- ./compiler/lua54.can:212 +destructured["rightOp"], -- ./compiler/lua54.can:212 +var, -- ./compiler/lua54.can:212 +val -- ./compiler/lua54.can:212 +} -- ./compiler/lua54.can:212 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 +val = { -- ./compiler/lua54.can:214 +["tag"] = "Op", -- ./compiler/lua54.can:214 +destructured["leftOp"], -- ./compiler/lua54.can:214 +val, -- ./compiler/lua54.can:214 +var -- ./compiler/lua54.can:214 +} -- ./compiler/lua54.can:214 +end -- ./compiler/lua54.can:214 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +end -- ./compiler/lua54.can:217 +if # vars > 0 then -- ./compiler/lua54.can:220 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 +if newlineAfter then -- ./compiler/lua54.can:222 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 +else -- ./compiler/lua54.can:223 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +else -- ./compiler/lua54.can:225 +return "" -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +end -- ./compiler/lua54.can:228 +tags = setmetatable({ -- ./compiler/lua54.can:233 +["Block"] = function(t) -- ./compiler/lua54.can:235 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 +hasPush = false -- ./compiler/lua54.can:239 +end -- ./compiler/lua54.can:239 +local r = push("scope", {}) -- ./compiler/lua54.can:241 +if hasPush then -- ./compiler/lua54.can:242 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 +end -- ./compiler/lua54.can:243 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 +end -- ./compiler/lua54.can:246 +if t[# t] then -- ./compiler/lua54.can:248 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +end -- ./compiler/lua54.can:249 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +end -- ./compiler/lua54.can:252 +return r .. pop("scope") -- ./compiler/lua54.can:254 +end, -- ./compiler/lua54.can:254 +["Do"] = function(t) -- ./compiler/lua54.can:260 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 +end, -- ./compiler/lua54.can:261 +["Set"] = function(t) -- ./compiler/lua54.can:264 +local expr = t[# t] -- ./compiler/lua54.can:266 +local vars, values = {}, {} -- ./compiler/lua54.can:267 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 +else -- ./compiler/lua54.can:272 +table["insert"](vars, n) -- ./compiler/lua54.can:274 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +end -- ./compiler/lua54.can:275 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 +local r = "" -- ./compiler/lua54.can:280 +if # vars > 0 then -- ./compiler/lua54.can:281 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 +end -- ./compiler/lua54.can:282 +if # destructuringVars > 0 then -- ./compiler/lua54.can:284 +local destructured = {} -- ./compiler/lua54.can:285 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 +end -- ./compiler/lua54.can:287 +return r -- ./compiler/lua54.can:289 +elseif # t == 4 then -- ./compiler/lua54.can:290 +if t[3] == "=" then -- ./compiler/lua54.can:291 +local r = "" -- ./compiler/lua54.can:292 +if # vars > 0 then -- ./compiler/lua54.can:293 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 +t[2], -- ./compiler/lua54.can:294 +vars[1], -- ./compiler/lua54.can:294 +{ -- ./compiler/lua54.can:294 +["tag"] = "Paren", -- ./compiler/lua54.can:294 +values[1] -- ./compiler/lua54.can:294 +} -- ./compiler/lua54.can:294 +}, "Op")) -- ./compiler/lua54.can:294 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 +t[2], -- ./compiler/lua54.can:296 +vars[i], -- ./compiler/lua54.can:296 +{ -- ./compiler/lua54.can:296 +["tag"] = "Paren", -- ./compiler/lua54.can:296 +values[i] -- ./compiler/lua54.can:296 +} -- ./compiler/lua54.can:296 +}, "Op")) -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +end -- ./compiler/lua54.can:296 +if # destructuringVars > 0 then -- ./compiler/lua54.can:299 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +end -- ./compiler/lua54.can:302 +return r -- ./compiler/lua54.can:304 +else -- ./compiler/lua54.can:304 +local r = "" -- ./compiler/lua54.can:306 +if # vars > 0 then -- ./compiler/lua54.can:307 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 +t[3], -- ./compiler/lua54.can:308 +{ -- ./compiler/lua54.can:308 +["tag"] = "Paren", -- ./compiler/lua54.can:308 +values[1] -- ./compiler/lua54.can:308 +}, -- ./compiler/lua54.can:308 +vars[1] -- ./compiler/lua54.can:308 +}, "Op")) -- ./compiler/lua54.can:308 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 +t[3], -- ./compiler/lua54.can:310 +{ -- ./compiler/lua54.can:310 +["tag"] = "Paren", -- ./compiler/lua54.can:310 +values[i] -- ./compiler/lua54.can:310 +}, -- ./compiler/lua54.can:310 +vars[i] -- ./compiler/lua54.can:310 +}, "Op")) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +if # destructuringVars > 0 then -- ./compiler/lua54.can:313 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:316 +return r -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +else -- ./compiler/lua54.can:318 +local r = "" -- ./compiler/lua54.can:321 +if # vars > 0 then -- ./compiler/lua54.can:322 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 +t[2], -- ./compiler/lua54.can:323 +vars[1], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Op", -- ./compiler/lua54.can:323 +t[4], -- ./compiler/lua54.can:323 +{ -- ./compiler/lua54.can:323 +["tag"] = "Paren", -- ./compiler/lua54.can:323 +values[1] -- ./compiler/lua54.can:323 +}, -- ./compiler/lua54.can:323 +vars[1] -- ./compiler/lua54.can:323 +} -- ./compiler/lua54.can:323 +}, "Op")) -- ./compiler/lua54.can:323 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 +t[2], -- ./compiler/lua54.can:325 +vars[i], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Op", -- ./compiler/lua54.can:325 +t[4], -- ./compiler/lua54.can:325 +{ -- ./compiler/lua54.can:325 +["tag"] = "Paren", -- ./compiler/lua54.can:325 +values[i] -- ./compiler/lua54.can:325 +}, -- ./compiler/lua54.can:325 +vars[i] -- ./compiler/lua54.can:325 +} -- ./compiler/lua54.can:325 +}, "Op")) -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +end -- ./compiler/lua54.can:325 +if # destructuringVars > 0 then -- ./compiler/lua54.can:328 +local destructured = { -- ./compiler/lua54.can:329 +["rightOp"] = t[2], -- ./compiler/lua54.can:329 +["leftOp"] = t[4] -- ./compiler/lua54.can:329 +} -- ./compiler/lua54.can:329 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +end -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end, -- ./compiler/lua54.can:333 +["While"] = function(t) -- ./compiler/lua54.can:337 +local r = "" -- ./compiler/lua54.can:338 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 +if # lets > 0 then -- ./compiler/lua54.can:341 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +end -- ./compiler/lua54.can:344 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 +if # lets > 0 then -- ./compiler/lua54.can:348 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 +end -- ./compiler/lua54.can:349 +if hasContinue then -- ./compiler/lua54.can:351 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 +if hasContinue then -- ./compiler/lua54.can:355 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 +end -- ./compiler/lua54.can:356 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 +if # lets > 0 then -- ./compiler/lua54.can:359 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 +end -- ./compiler/lua54.can:361 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 +end -- ./compiler/lua54.can:363 +return r -- ./compiler/lua54.can:365 +end, -- ./compiler/lua54.can:365 +["Repeat"] = function(t) -- ./compiler/lua54.can:368 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 +local r = "repeat" .. indent() -- ./compiler/lua54.can:370 +if hasContinue then -- ./compiler/lua54.can:371 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 +end -- ./compiler/lua54.can:372 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 +if hasContinue then -- ./compiler/lua54.can:375 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 +end -- ./compiler/lua54.can:376 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 +return r -- ./compiler/lua54.can:379 +end, -- ./compiler/lua54.can:379 +["If"] = function(t) -- ./compiler/lua54.can:382 +local r = "" -- ./compiler/lua54.can:383 +local toClose = 0 -- ./compiler/lua54.can:384 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 +if # lets > 0 then -- ./compiler/lua54.can:386 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 +toClose = toClose + (1) -- ./compiler/lua54.can:388 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +end -- ./compiler/lua54.can:390 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 +if # lets > 0 then -- ./compiler/lua54.can:396 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 +toClose = toClose + (1) -- ./compiler/lua54.can:398 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 +end -- ./compiler/lua54.can:400 +else -- ./compiler/lua54.can:400 +r = r .. ("else") -- ./compiler/lua54.can:403 +end -- ./compiler/lua54.can:403 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 +end -- ./compiler/lua54.can:405 +if # t % 2 == 1 then -- ./compiler/lua54.can:407 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +r = r .. ("end") -- ./compiler/lua54.can:410 +for i = 1, toClose do -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 +end -- ./compiler/lua54.can:412 +return r -- ./compiler/lua54.can:414 +end, -- ./compiler/lua54.can:414 +["Fornum"] = function(t) -- ./compiler/lua54.can:417 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 +if # t == 5 then -- ./compiler/lua54.can:419 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 +if hasContinue then -- ./compiler/lua54.can:422 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 +end -- ./compiler/lua54.can:423 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 +if hasContinue then -- ./compiler/lua54.can:426 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 +end -- ./compiler/lua54.can:427 +return r .. unindent() .. "end" -- ./compiler/lua54.can:429 +else -- ./compiler/lua54.can:429 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 +if hasContinue then -- ./compiler/lua54.can:433 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 +end -- ./compiler/lua54.can:434 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 +if hasContinue then -- ./compiler/lua54.can:437 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 +end -- ./compiler/lua54.can:438 +return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:440 +end, -- ./compiler/lua54.can:440 +["Forin"] = function(t) -- ./compiler/lua54.can:444 +local destructured = {} -- ./compiler/lua54.can:445 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 +if hasContinue then -- ./compiler/lua54.can:448 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 +end -- ./compiler/lua54.can:449 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 +if hasContinue then -- ./compiler/lua54.can:452 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 +end -- ./compiler/lua54.can:453 +return r .. unindent() .. "end" -- ./compiler/lua54.can:455 +end, -- ./compiler/lua54.can:455 +["Local"] = function(t) -- ./compiler/lua54.can:458 +local destructured = {} -- ./compiler/lua54.can:459 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 +if t[2][1] then -- ./compiler/lua54.can:461 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 +end -- ./compiler/lua54.can:462 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 +end, -- ./compiler/lua54.can:464 +["Let"] = function(t) -- ./compiler/lua54.can:467 +local destructured = {} -- ./compiler/lua54.can:468 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 +local r = "local " .. nameList -- ./compiler/lua54.can:470 +if t[2][1] then -- ./compiler/lua54.can:471 +if all(t[2], { -- ./compiler/lua54.can:472 +"Nil", -- ./compiler/lua54.can:472 +"Dots", -- ./compiler/lua54.can:472 +"Boolean", -- ./compiler/lua54.can:472 +"Number", -- ./compiler/lua54.can:472 +"String" -- ./compiler/lua54.can:472 +}) then -- ./compiler/lua54.can:472 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 +else -- ./compiler/lua54.can:473 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +end -- ./compiler/lua54.can:475 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 +end, -- ./compiler/lua54.can:478 +["Localrec"] = function(t) -- ./compiler/lua54.can:481 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 +end, -- ./compiler/lua54.can:482 +["Goto"] = function(t) -- ./compiler/lua54.can:485 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Label"] = function(t) -- ./compiler/lua54.can:489 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Return"] = function(t) -- ./compiler/lua54.can:493 +local push = peek("push") -- ./compiler/lua54.can:494 +if push then -- ./compiler/lua54.can:495 +local r = "" -- ./compiler/lua54.can:496 +for _, val in ipairs(t) do -- ./compiler/lua54.can:497 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 +end -- ./compiler/lua54.can:498 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 +else -- ./compiler/lua54.can:500 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 +end -- ./compiler/lua54.can:502 +end, -- ./compiler/lua54.can:502 +["Push"] = function(t) -- ./compiler/lua54.can:506 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 +r = "" -- ./compiler/lua54.can:508 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +if t[# t] then -- ./compiler/lua54.can:512 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 +else -- ./compiler/lua54.can:514 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +end -- ./compiler/lua54.can:516 +return r -- ./compiler/lua54.can:519 +end, -- ./compiler/lua54.can:519 +["Break"] = function() -- ./compiler/lua54.can:522 +return "break" -- ./compiler/lua54.can:523 +end, -- ./compiler/lua54.can:523 +["Continue"] = function() -- ./compiler/lua54.can:526 +return "goto " .. var("continue") -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Nil"] = function() -- ./compiler/lua54.can:534 +return "nil" -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Dots"] = function() -- ./compiler/lua54.can:538 +return "..." -- ./compiler/lua54.can:539 +end, -- ./compiler/lua54.can:539 +["Boolean"] = function(t) -- ./compiler/lua54.can:542 +return tostring(t[1]) -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Number"] = function(t) -- ./compiler/lua54.can:546 +return tostring(t[1]) -- ./compiler/lua54.can:547 +end, -- ./compiler/lua54.can:547 +["String"] = function(t) -- ./compiler/lua54.can:550 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 +end, -- ./compiler/lua54.can:551 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 +local r = "(" -- ./compiler/lua54.can:555 +local decl = {} -- ./compiler/lua54.can:556 +if t[1][1] then -- ./compiler/lua54.can:557 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 +r = r .. (id) -- ./compiler/lua54.can:563 +else -- ./compiler/lua54.can:563 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 +end -- ./compiler/lua54.can:565 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 +r = r .. (", " .. id) -- ./compiler/lua54.can:573 +else -- ./compiler/lua54.can:573 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +end -- ./compiler/lua54.can:575 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 +r = r .. (d .. newline()) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 +end -- ./compiler/lua54.can:584 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 +if hasPush then -- ./compiler/lua54.can:587 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 +else -- ./compiler/lua54.can:588 +push("push", false) -- ./compiler/lua54.can:590 +end -- ./compiler/lua54.can:590 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 +end -- ./compiler/lua54.can:594 +pop("push") -- ./compiler/lua54.can:596 +return r .. unindent() .. "end" -- ./compiler/lua54.can:597 +end, -- ./compiler/lua54.can:597 +["Function"] = function(t) -- ./compiler/lua54.can:599 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 +end, -- ./compiler/lua54.can:600 +["Pair"] = function(t) -- ./compiler/lua54.can:603 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 +end, -- ./compiler/lua54.can:604 +["Table"] = function(t) -- ./compiler/lua54.can:606 +if # t == 0 then -- ./compiler/lua54.can:607 +return "{}" -- ./compiler/lua54.can:608 +elseif # t == 1 then -- ./compiler/lua54.can:609 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 +else -- ./compiler/lua54.can:610 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 +end -- ./compiler/lua54.can:612 +end, -- ./compiler/lua54.can:612 +["TableCompr"] = function(t) -- ./compiler/lua54.can:616 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 +end, -- ./compiler/lua54.can:617 +["Op"] = function(t) -- ./compiler/lua54.can:620 +local r -- ./compiler/lua54.can:621 +if # t == 2 then -- ./compiler/lua54.can:622 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +else -- ./compiler/lua54.can:624 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +end -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 +else -- ./compiler/lua54.can:630 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +end -- ./compiler/lua54.can:632 +return r -- ./compiler/lua54.can:635 +end, -- ./compiler/lua54.can:635 +["Paren"] = function(t) -- ./compiler/lua54.can:638 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 +end, -- ./compiler/lua54.can:639 +["MethodStub"] = function(t) -- ./compiler/lua54.can:642 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 +end, -- ./compiler/lua54.can:648 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 +end, -- ./compiler/lua54.can:658 +["LetExpr"] = function(t) -- ./compiler/lua54.can:665 +return lua(t[1][1]) -- ./compiler/lua54.can:666 +end, -- ./compiler/lua54.can:666 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 +local r = "(function()" .. indent() -- ./compiler/lua54.can:672 +if hasPush then -- ./compiler/lua54.can:673 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 +else -- ./compiler/lua54.can:674 +push("push", false) -- ./compiler/lua54.can:676 +end -- ./compiler/lua54.can:676 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 +if hasPush then -- ./compiler/lua54.can:679 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 +end -- ./compiler/lua54.can:680 +pop("push") -- ./compiler/lua54.can:682 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 +return r -- ./compiler/lua54.can:684 +end, -- ./compiler/lua54.can:684 +["DoExpr"] = function(t) -- ./compiler/lua54.can:687 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 +end -- ./compiler/lua54.can:689 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 +end, -- ./compiler/lua54.can:691 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 +end, -- ./compiler/lua54.can:695 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 +end, -- ./compiler/lua54.can:699 +["IfExpr"] = function(t) -- ./compiler/lua54.can:702 +for i = 2, # t do -- ./compiler/lua54.can:703 +local block = t[i] -- ./compiler/lua54.can:704 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +end -- ./compiler/lua54.can:706 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:709 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +end, -- ./compiler/lua54.can:713 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 +end, -- ./compiler/lua54.can:717 +["Call"] = function(t) -- ./compiler/lua54.can:723 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 +else -- ./compiler/lua54.can:728 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 +end -- ./compiler/lua54.can:730 +else -- ./compiler/lua54.can:730 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 +end -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["SafeCall"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 +else -- ./compiler/lua54.can:739 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 +end -- ./compiler/lua54.can:741 +end, -- ./compiler/lua54.can:741 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 +if start == nil then start = 1 end -- ./compiler/lua54.can:746 +local r -- ./compiler/lua54.can:747 +if t[start] then -- ./compiler/lua54.can:748 +r = lua(t[start]) -- ./compiler/lua54.can:749 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 +end -- ./compiler/lua54.can:751 +else -- ./compiler/lua54.can:751 +r = "" -- ./compiler/lua54.can:754 +end -- ./compiler/lua54.can:754 +return r -- ./compiler/lua54.can:756 +end, -- ./compiler/lua54.can:756 +["Id"] = function(t) -- ./compiler/lua54.can:759 +return t[1] -- ./compiler/lua54.can:760 +end, -- ./compiler/lua54.can:760 +["AttributeId"] = function(t) -- ./compiler/lua54.can:763 +if t[2] then -- ./compiler/lua54.can:764 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 +else -- ./compiler/lua54.can:765 +return t[1] -- ./compiler/lua54.can:767 +end -- ./compiler/lua54.can:767 +end, -- ./compiler/lua54.can:767 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 +if t["id"] then -- ./compiler/lua54.can:772 +return t["id"] -- ./compiler/lua54.can:773 +else -- ./compiler/lua54.can:773 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 +for j = 1, # t, 1 do -- ./compiler/lua54.can:777 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 +end -- ./compiler/lua54.can:778 +table["insert"](d, vars) -- ./compiler/lua54.can:780 +t["id"] = vars["id"] -- ./compiler/lua54.can:781 +return vars["id"] -- ./compiler/lua54.can:782 +end -- ./compiler/lua54.can:782 +end, -- ./compiler/lua54.can:782 +["Index"] = function(t) -- ./compiler/lua54.can:786 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 +else -- ./compiler/lua54.can:788 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +end -- ./compiler/lua54.can:790 +end, -- ./compiler/lua54.can:790 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 +local l = {} -- ./compiler/lua54.can:796 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 +table["insert"](l, 1, t) -- ./compiler/lua54.can:798 +t = t[1] -- ./compiler/lua54.can:799 +end -- ./compiler/lua54.can:799 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 +for _, e in ipairs(l) do -- ./compiler/lua54.can:802 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 +else -- ./compiler/lua54.can:805 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +end -- ./compiler/lua54.can:807 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 +return r -- ./compiler/lua54.can:811 +else -- ./compiler/lua54.can:811 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 +end -- ./compiler/lua54.can:813 +end, -- ./compiler/lua54.can:813 +["_opid"] = { -- ./compiler/lua54.can:818 +["add"] = "+", -- ./compiler/lua54.can:819 +["sub"] = "-", -- ./compiler/lua54.can:819 +["mul"] = "*", -- ./compiler/lua54.can:819 +["div"] = "/", -- ./compiler/lua54.can:819 +["idiv"] = "//", -- ./compiler/lua54.can:820 +["mod"] = "%", -- ./compiler/lua54.can:820 +["pow"] = "^", -- ./compiler/lua54.can:820 +["concat"] = "..", -- ./compiler/lua54.can:820 +["band"] = "&", -- ./compiler/lua54.can:821 +["bor"] = "|", -- ./compiler/lua54.can:821 +["bxor"] = "~", -- ./compiler/lua54.can:821 +["shl"] = "<<", -- ./compiler/lua54.can:821 +["shr"] = ">>", -- ./compiler/lua54.can:821 +["eq"] = "==", -- ./compiler/lua54.can:822 +["ne"] = "~=", -- ./compiler/lua54.can:822 +["lt"] = "<", -- ./compiler/lua54.can:822 +["gt"] = ">", -- ./compiler/lua54.can:822 +["le"] = "<=", -- ./compiler/lua54.can:822 +["ge"] = ">=", -- ./compiler/lua54.can:822 +["and"] = "and", -- ./compiler/lua54.can:823 +["or"] = "or", -- ./compiler/lua54.can:823 +["unm"] = "-", -- ./compiler/lua54.can:823 +["len"] = "#", -- ./compiler/lua54.can:823 +["bnot"] = "~", -- ./compiler/lua54.can:823 +["not"] = "not" -- ./compiler/lua54.can:823 +} -- ./compiler/lua54.can:823 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 +end }) -- ./compiler/lua54.can:827 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +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 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 +return requireStr .. code -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +end -- ./compiler/lua54.can:834 +local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +return lua54 -- ./compiler/lua53.can:18 +end -- ./compiler/lua53.can:18 +local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +return lua53 -- ./compiler/lua52.can:35 +end -- ./compiler/lua52.can:35 +local lua52 = _() or lua52 -- ./compiler/lua52.can:39 +return lua52 -- ./compiler/luajit.can:38 +end -- ./compiler/luajit.can:38 +local luajit = _() or luajit -- ./compiler/luajit.can:42 +package["loaded"]["compiler.luajit"] = luajit or true -- ./compiler/luajit.can:43 +local function _() -- ./compiler/luajit.can:46 +local function _() -- ./compiler/luajit.can:48 +local function _() -- ./compiler/luajit.can:50 local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 -local function _() -- ./compiler/luajit.can:56 -local function _() -- ./compiler/luajit.can:58 local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 return function(code, ast, options) -- ./compiler/lua54.can:3 local lastInputPos = 1 -- ./compiler/lua54.can:5 @@ -3604,27 +4565,108 @@ end }) -- ./compiler/lua54.can:827 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 -error("target does not support variable attributes") -- ./compiler/lua53.can:6 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +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 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 +targetName = "Lua 5.1" -- ./compiler/lua51.can:1 +states["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"] = function() -- ./compiler/lua51.can:25 +error("target " .. targetName .. " does not support gotos") -- ./compiler/lua51.can:26 +end -- ./compiler/lua51.can:26 +tags["Label"] = function() -- ./compiler/lua51.can:28 +error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 +end -- ./compiler/lua51.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 return requireStr .. code -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 end -- ./compiler/lua54.can:834 local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -return lua54 -- ./compiler/lua53.can:16 -end -- ./compiler/lua53.can:16 -local lua53 = _() or lua53 -- ./compiler/lua53.can:20 -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 +return lua54 -- ./compiler/lua53.can:18 +end -- ./compiler/lua53.can:18 +local lua53 = _() or lua53 -- ./compiler/lua53.can:22 +return lua53 -- ./compiler/lua52.can:35 +end -- ./compiler/lua52.can:35 +local lua52 = _() or lua52 -- ./compiler/lua52.can:39 +return lua52 -- ./compiler/luajit.can:38 +end -- ./compiler/luajit.can:38 +local luajit = _() or luajit -- ./compiler/luajit.can:42 +return luajit -- ./compiler/lua51.can:38 +end -- ./compiler/lua51.can:38 +local lua51 = _() or lua51 -- ./compiler/lua51.can:42 +package["loaded"]["compiler.lua51"] = lua51 or true -- ./compiler/lua51.can:43 +local function _() -- ./compiler/lua51.can:47 local scope = {} -- ./candran/can-parser/scope.lua:4 scope["lineno"] = function(s, i) -- ./candran/can-parser/scope.lua:6 if i == 1 then -- ./candran/can-parser/scope.lua:7 @@ -5355,260 +6397,260 @@ return parser -- ./candran/can-parser/parser.lua:777 end -- ./candran/can-parser/parser.lua:777 local parser = _() or parser -- ./candran/can-parser/parser.lua:781 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 -local unpack = unpack or table["unpack"] -- candran.can:14 -local candran = { ["VERSION"] = "0.13.1" } -- candran.can:17 -candran["default"] = { -- candran.can:21 -["target"] = "lua54", -- candran.can:22 -["indentation"] = "", -- candran.can:23 +local unpack = unpack or table["unpack"] -- candran.can:15 +local candran = { ["VERSION"] = "0.13.1" } -- candran.can:18 +candran["default"] = { -- candran.can:22 +["target"] = "lua54", -- candran.can:23 +["indentation"] = "", -- candran.can:24 ["newline"] = "\ -", -- candran.can:24 -["variablePrefix"] = "__CAN_", -- candran.can:25 -["mapLines"] = true, -- candran.can:26 -["chunkname"] = "nil", -- candran.can:27 -["rewriteErrors"] = true -- candran.can:28 -} -- candran.can:28 -if _VERSION == "Lua 5.1" then -- candran.can:32 -if package["loaded"]["jit"] then -- candran.can:33 -candran["default"]["target"] = "luajit" -- candran.can:34 -else -- candran.can:34 -candran["default"]["target"] = "lua51" -- candran.can:36 -end -- candran.can:36 -elseif _VERSION == "Lua 5.2" then -- candran.can:38 -candran["default"]["target"] = "lua51" -- candran.can:39 -elseif _VERSION == "Lua 5.3" then -- candran.can:40 -candran["default"]["target"] = "lua53" -- candran.can:41 -end -- candran.can:41 -candran["preprocess"] = function(input, options) -- candran.can:50 -if options == nil then options = {} end -- candran.can:50 -options = util["merge"](candran["default"], options) -- candran.can:51 -local preprocessor = "" -- candran.can:54 -local i = 0 -- candran.can:55 -local inLongString = false -- candran.can:56 -local inComment = false -- candran.can:57 +", -- candran.can:25 +["variablePrefix"] = "__CAN_", -- candran.can:26 +["mapLines"] = true, -- candran.can:27 +["chunkname"] = "nil", -- candran.can:28 +["rewriteErrors"] = true -- candran.can:29 +} -- candran.can:29 +if _VERSION == "Lua 5.1" then -- candran.can:33 +if package["loaded"]["jit"] then -- candran.can:34 +candran["default"]["target"] = "luajit" -- candran.can:35 +else -- candran.can:35 +candran["default"]["target"] = "lua51" -- candran.can:37 +end -- candran.can:37 +elseif _VERSION == "Lua 5.2" then -- candran.can:39 +candran["default"]["target"] = "lua52" -- candran.can:40 +elseif _VERSION == "Lua 5.3" then -- candran.can:41 +candran["default"]["target"] = "lua53" -- candran.can:42 +end -- candran.can:42 +candran["preprocess"] = function(input, options) -- candran.can:51 +if options == nil then options = {} end -- candran.can:51 +options = util["merge"](candran["default"], options) -- candran.can:52 +local preprocessor = "" -- candran.can:55 +local i = 0 -- candran.can:56 +local inLongString = false -- candran.can:57 +local inComment = false -- candran.can:58 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:58 -i = i + (1) -- candran.can:59 -if inComment then -- candran.can:61 -inComment = not line:match("%]%]") -- candran.can:62 -elseif inLongString then -- candran.can:63 -inLongString = not line:match("%]%]") -- candran.can:64 -else -- candran.can:64 -if line:match("[^%-]%[%[") then -- candran.can:66 -inLongString = true -- candran.can:67 -elseif line:match("%-%-%[%[") then -- candran.can:68 -inComment = true -- candran.can:69 -end -- candran.can:69 -end -- candran.can:69 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:72 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:73 -else -- candran.can:73 -local l = line:sub(1, - 2) -- candran.can:75 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:76 +)") do -- candran.can:59 +i = i + (1) -- candran.can:60 +if inComment then -- candran.can:62 +inComment = not line:match("%]%]") -- candran.can:63 +elseif inLongString then -- candran.can:64 +inLongString = not line:match("%]%]") -- candran.can:65 +else -- candran.can:65 +if line:match("[^%-]%[%[") then -- candran.can:67 +inLongString = true -- candran.can:68 +elseif line:match("%-%-%[%[") then -- candran.can:69 +inComment = true -- candran.can:70 +end -- candran.can:70 +end -- candran.can:70 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:73 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:74 +else -- candran.can:74 +local l = line:sub(1, - 2) -- candran.can:76 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:77 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:77 -else -- candran.can:77 +") -- candran.can:78 +else -- candran.can:78 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:79 -end -- candran.can:79 -end -- candran.can:79 -end -- candran.can:79 -preprocessor = preprocessor .. ("return output") -- candran.can:83 -local env = util["merge"](_G, options) -- candran.can:86 -env["candran"] = candran -- candran.can:88 -env["output"] = "" -- candran.can:90 -env["import"] = function(modpath, margs) -- candran.can:97 -if margs == nil then margs = {} end -- candran.can:97 -local filepath = assert(util["search"](modpath, { -- candran.can:98 -"can", -- candran.can:98 -"lua" -- candran.can:98 -}), "No module named \"" .. modpath .. "\"") -- candran.can:98 -local f = io["open"](filepath) -- candran.can:101 -if not f then -- candran.can:102 -error("can't open the module file to import") -- candran.can:102 -end -- candran.can:102 -margs = util["merge"](options, { -- candran.can:104 -["chunkname"] = filepath, -- candran.can:104 -["loadLocal"] = true, -- candran.can:104 -["loadPackage"] = true -- candran.can:104 -}, margs) -- candran.can:104 -local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:105 -f:close() -- candran.can:106 -local modname = modpath:match("[^%.]+$") -- candran.can:109 +") -- candran.can:80 +end -- candran.can:80 +end -- candran.can:80 +end -- candran.can:80 +preprocessor = preprocessor .. ("return output") -- candran.can:84 +local env = util["merge"](_G, options) -- candran.can:87 +env["candran"] = candran -- candran.can:89 +env["output"] = "" -- candran.can:91 +env["import"] = function(modpath, margs) -- candran.can:98 +if margs == nil then margs = {} end -- candran.can:98 +local filepath = assert(util["search"](modpath, { -- candran.can:99 +"can", -- candran.can:99 +"lua" -- candran.can:99 +}), "No module named \"" .. modpath .. "\"") -- candran.can:99 +local f = io["open"](filepath) -- candran.can:102 +if not f then -- candran.can:103 +error("can't open the module file to import") -- candran.can:103 +end -- candran.can:103 +margs = util["merge"](options, { -- candran.can:105 +["chunkname"] = filepath, -- candran.can:105 +["loadLocal"] = true, -- candran.can:105 +["loadPackage"] = true -- candran.can:105 +}, margs) -- candran.can:105 +local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:106 +f:close() -- candran.can:107 +local modname = modpath:match("[^%.]+$") -- candran.can:110 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:118 -end -- candran.can:118 -env["include"] = function(file) -- candran.can:123 -local f = io["open"](file) -- candran.can:124 -if not f then -- candran.can:125 -error("can't open the file " .. file .. " to include") -- candran.can:125 -end -- candran.can:125 -env["write"](f:read("*a")) -- candran.can:126 -f:close() -- candran.can:127 -end -- candran.can:127 -env["write"] = function(...) -- candran.can:131 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:119 +end -- candran.can:119 +env["include"] = function(file) -- candran.can:124 +local f = io["open"](file) -- candran.can:125 +if not f then -- candran.can:126 +error("can't open the file " .. file .. " to include") -- candran.can:126 +end -- candran.can:126 +env["write"](f:read("*a")) -- candran.can:127 +f:close() -- candran.can:128 +end -- candran.can:128 +env["write"] = function(...) -- candran.can:132 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:132 -end -- candran.can:132 -env["placeholder"] = function(name) -- candran.can:136 -if env[name] then -- candran.can:137 -env["write"](env[name]) -- candran.can:138 -end -- candran.can:138 -end -- candran.can:138 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:143 -if not preprocess then -- candran.can:144 -return nil, "in preprocessor: " .. err -- candran.can:145 -end -- candran.can:145 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:148 -if not preprocess then -- candran.can:149 -return nil, "in preprocessor: " .. err -- candran.can:150 -end -- candran.can:150 -local success, output = pcall(preprocess) -- candran.can:154 -if not success then -- candran.can:155 -return nil, "in preprocessor: " .. output -- candran.can:156 -end -- candran.can:156 -return output -- candran.can:159 -end -- candran.can:159 -candran["compile"] = function(input, options) -- candran.can:168 -if options == nil then options = {} end -- candran.can:168 -options = util["merge"](candran["default"], options) -- candran.can:169 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:171 -if not ast then -- candran.can:173 -return nil, errmsg -- candran.can:174 -end -- candran.can:174 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:177 -end -- candran.can:177 -candran["make"] = function(code, options) -- candran.can:186 -local r, err = candran["preprocess"](code, options) -- candran.can:187 -if r then -- candran.can:188 -r, err = candran["compile"](r, options) -- candran.can:189 -if r then -- candran.can:190 -return r -- candran.can:191 -end -- candran.can:191 -end -- candran.can:191 -return r, err -- candran.can:194 -end -- candran.can:194 -local errorRewritingActive = false -- candran.can:197 -local codeCache = {} -- candran.can:198 -candran["loadfile"] = function(filepath, env, options) -- candran.can:201 -local f, err = io["open"](filepath) -- candran.can:202 -if not f then -- candran.can:203 -return nil, ("cannot open %s"):format(err) -- candran.can:204 -end -- candran.can:204 -local content = f:read("*a") -- candran.can:206 -f:close() -- candran.can:207 -return candran["load"](content, filepath, env, options) -- candran.can:209 -end -- candran.can:209 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:214 -if options == nil then options = {} end -- candran.can:214 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:215 -local code, err = candran["make"](chunk, options) -- candran.can:217 -if not code then -- candran.can:218 -return code, err -- candran.can:219 -end -- candran.can:219 -codeCache[options["chunkname"]] = code -- candran.can:222 -local f, err = util["load"](code, options["chunkname"], env) -- candran.can:223 -if f == nil then -- candran.can:228 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:229 -end -- candran.can:229 -if options["rewriteErrors"] == false then -- candran.can:232 -return f -- candran.can:233 -else -- candran.can:233 -return function(...) -- candran.can:235 -local params = { ... } -- candran.can:236 -if not errorRewritingActive then -- candran.can:237 -errorRewritingActive = true -- candran.can:238 -local t = { xpcall(function() -- candran.can:239 -return f(unpack(params)) -- candran.can:239 -end, candran["messageHandler"]) } -- candran.can:239 -errorRewritingActive = false -- candran.can:240 -if t[1] == false then -- candran.can:241 -error(t[2], 0) -- candran.can:242 -end -- candran.can:242 -return unpack(t, 2) -- candran.can:244 -else -- candran.can:244 -return f(...) -- candran.can:246 -end -- candran.can:246 -end -- candran.can:246 -end -- candran.can:246 -end -- candran.can:246 -candran["dofile"] = function(filename, options) -- candran.can:254 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:255 -if f == nil then -- candran.can:257 -error(err) -- candran.can:258 -else -- candran.can:258 -return f() -- candran.can:260 -end -- candran.can:260 -end -- candran.can:260 -candran["messageHandler"] = function(message) -- candran.can:266 +") -- candran.can:133 +end -- candran.can:133 +env["placeholder"] = function(name) -- candran.can:137 +if env[name] then -- candran.can:138 +env["write"](env[name]) -- candran.can:139 +end -- candran.can:139 +end -- candran.can:139 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:144 +if not preprocess then -- candran.can:145 +return nil, "in preprocessor: " .. err -- candran.can:146 +end -- candran.can:146 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:149 +if not preprocess then -- candran.can:150 +return nil, "in preprocessor: " .. err -- candran.can:151 +end -- candran.can:151 +local success, output = pcall(preprocess) -- candran.can:155 +if not success then -- candran.can:156 +return nil, "in preprocessor: " .. output -- candran.can:157 +end -- candran.can:157 +return output -- candran.can:160 +end -- candran.can:160 +candran["compile"] = function(input, options) -- candran.can:169 +if options == nil then options = {} end -- candran.can:169 +options = util["merge"](candran["default"], options) -- candran.can:170 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:172 +if not ast then -- candran.can:174 +return nil, errmsg -- candran.can:175 +end -- candran.can:175 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:178 +end -- candran.can:178 +candran["make"] = function(code, options) -- candran.can:187 +local r, err = candran["preprocess"](code, options) -- candran.can:188 +if r then -- candran.can:189 +r, err = candran["compile"](r, options) -- candran.can:190 +if r then -- candran.can:191 +return r -- candran.can:192 +end -- candran.can:192 +end -- candran.can:192 +return r, err -- candran.can:195 +end -- candran.can:195 +local errorRewritingActive = false -- candran.can:198 +local codeCache = {} -- candran.can:199 +candran["loadfile"] = function(filepath, env, options) -- candran.can:202 +local f, err = io["open"](filepath) -- candran.can:203 +if not f then -- candran.can:204 +return nil, ("cannot open %s"):format(err) -- candran.can:205 +end -- candran.can:205 +local content = f:read("*a") -- candran.can:207 +f:close() -- candran.can:208 +return candran["load"](content, filepath, env, options) -- candran.can:210 +end -- candran.can:210 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:215 +if options == nil then options = {} end -- candran.can:215 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:216 +local code, err = candran["make"](chunk, options) -- candran.can:218 +if not code then -- candran.can:219 +return code, err -- candran.can:220 +end -- candran.can:220 +codeCache[options["chunkname"]] = code -- candran.can:223 +local f, err = util["load"](code, options["chunkname"], env) -- candran.can:224 +if f == nil then -- candran.can:229 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:230 +end -- candran.can:230 +if options["rewriteErrors"] == false then -- candran.can:233 +return f -- candran.can:234 +else -- candran.can:234 +return function(...) -- candran.can:236 +local params = { ... } -- candran.can:237 +if not errorRewritingActive then -- candran.can:238 +errorRewritingActive = true -- candran.can:239 +local t = { xpcall(function() -- candran.can:240 +return f(unpack(params)) -- candran.can:240 +end, candran["messageHandler"]) } -- candran.can:240 +errorRewritingActive = false -- candran.can:241 +if t[1] == false then -- candran.can:242 +error(t[2], 0) -- candran.can:243 +end -- candran.can:243 +return unpack(t, 2) -- candran.can:245 +else -- candran.can:245 +return f(...) -- candran.can:247 +end -- candran.can:247 +end -- candran.can:247 +end -- candran.can:247 +end -- candran.can:247 +candran["dofile"] = function(filename, options) -- candran.can:255 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:256 +if f == nil then -- candran.can:258 +error(err) -- candran.can:259 +else -- candran.can:259 +return f() -- candran.can:261 +end -- candran.can:261 +end -- candran.can:261 +candran["messageHandler"] = function(message) -- candran.can:267 return debug["traceback"](message, 2):gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:267 -line = tonumber(line) -- candran.can:268 -local originalFile -- candran.can:270 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:271 -if strName then -- candran.can:272 -if codeCache[strName] then -- candran.can:273 -originalFile = codeCache[strName] -- candran.can:274 -source = strName -- candran.can:275 -end -- candran.can:275 -else -- candran.can:275 -local fi = io["open"](source, "r") -- candran.can:278 -if fi then -- candran.can:279 -originalFile = fi:read("*a") -- candran.can:280 -fi:close() -- candran.can:281 -end -- candran.can:281 -end -- candran.can:281 -if originalFile then -- candran.can:285 -local i = 0 -- candran.can:286 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:268 +line = tonumber(line) -- candran.can:269 +local originalFile -- candran.can:271 +local strName = source:match("%[string \"(.-)\"%]") -- candran.can:272 +if strName then -- candran.can:273 +if codeCache[strName] then -- candran.can:274 +originalFile = codeCache[strName] -- candran.can:275 +source = strName -- candran.can:276 +end -- candran.can:276 +else -- candran.can:276 +local fi = io["open"](source, "r") -- candran.can:279 +if fi then -- candran.can:280 +originalFile = fi:read("*a") -- candran.can:281 +fi:close() -- candran.can:282 +end -- candran.can:282 +end -- candran.can:282 +if originalFile then -- candran.can:286 +local i = 0 -- candran.can:287 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:287 -i = i + 1 -- candran.can:288 -if i == line then -- candran.can:289 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:290 -if lineMap then -- candran.can:291 -if extSource ~= source then -- candran.can:292 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:293 -else -- candran.can:293 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:295 -end -- candran.can:295 -end -- candran.can:295 -break -- candran.can:298 -end -- candran.can:298 -end -- candran.can:298 -end -- candran.can:298 -end) -- candran.can:298 -end -- candran.can:298 -candran["searcher"] = function(modpath) -- candran.can:306 -local filepath = util["search"](modpath, { "can" }) -- candran.can:307 -if not filepath then -- candran.can:308 -if _VERSION == "Lua 5.4" then -- candran.can:309 -return "no candran file in package.path" -- candran.can:310 -else -- candran.can:310 +") do -- candran.can:288 +i = i + 1 -- candran.can:289 +if i == line then -- candran.can:290 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:291 +if lineMap then -- candran.can:292 +if extSource ~= source then -- candran.can:293 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:294 +else -- candran.can:294 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:296 +end -- candran.can:296 +end -- candran.can:296 +break -- candran.can:299 +end -- candran.can:299 +end -- candran.can:299 +end -- candran.can:299 +end) -- candran.can:299 +end -- candran.can:299 +candran["searcher"] = function(modpath) -- candran.can:307 +local filepath = util["search"](modpath, { "can" }) -- candran.can:308 +if not filepath then -- candran.can:309 +if _VERSION == "Lua 5.4" then -- candran.can:310 +return "no candran file in package.path" -- candran.can:311 +else -- candran.can:311 return "\ -\9no candran file in package.path" -- candran.can:312 -end -- candran.can:312 -end -- candran.can:312 -local r, s = candran["loadfile"](filepath) -- candran.can:315 -if r then -- candran.can:316 -return r -- candran.can:317 -else -- candran.can:317 -return s -- candran.can:319 -end -- candran.can:319 -end -- candran.can:319 -candran["setup"] = function() -- candran.can:324 -if _VERSION == "Lua 5.1" then -- candran.can:325 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:326 -else -- candran.can:326 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:328 -end -- candran.can:328 -return candran -- candran.can:330 -end -- candran.can:330 -return candran -- candran.can:333 +\9no candran file in package.path" -- candran.can:313 +end -- candran.can:313 +end -- candran.can:313 +local r, s = candran["loadfile"](filepath) -- candran.can:316 +if r then -- candran.can:317 +return r -- candran.can:318 +else -- candran.can:318 +return s -- candran.can:320 +end -- candran.can:320 +end -- candran.can:320 +candran["setup"] = function() -- candran.can:325 +if _VERSION == "Lua 5.1" then -- candran.can:326 +table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:327 +else -- candran.can:327 +table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:329 +end -- candran.can:329 +return candran -- candran.can:331 +end -- candran.can:331 +return candran -- candran.can:334 diff --git a/compiler/lua51.can b/compiler/lua51.can index 2238d70..9443454 100644 --- a/compiler/lua51.can +++ b/compiler/lua51.can @@ -22,8 +22,14 @@ tags.Break = () end -- Unsuported features -tags.Goto = nil -tags.Label = nil +tags.Goto = () + error("target "..targetName.." does not support gotos") +end +tags.Label = () + error("target "..targetName.." does not support goto labels") +end + +#placeholder("patch") #local patch = output #output = "" diff --git a/compiler/lua52.can b/compiler/lua52.can new file mode 100644 index 0000000..7f94efc --- /dev/null +++ b/compiler/lua52.can @@ -0,0 +1,35 @@ +targetName = "Lua 5.2" + +APPEND = (t, toAppend) + return "do" .. indent() .. "local "..var("a")..", "..var("p").." = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #"..var("a").." do" .. indent() .. t .. "["..var("p").."] = "..var("a").."[i]" .. newline() .. ""..var("p").." = "..var("p").." + 1" .. unindent() .. "end" .. unindent() .. "end" +end + +tags._opid.idiv = (left, right) + return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" +end +tags._opid.band = (left, right) + return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" +end +tags._opid.bor = (left, right) + return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" +end +tags._opid.bxor = (left, right) + return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" +end +tags._opid.shl = (left, right) + return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" +end +tags._opid.shr = (left, right) + return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" +end +tags._opid.bnot = (right) + return "bit32.bnot(" .. lua(right) .. ")" +end + +#placeholder("patch") + +#local patch = output +#output = "" +#import("compiler.lua53", { patch = patch, loadPackage = false }) + +return lua53 diff --git a/compiler/lua53.can b/compiler/lua53.can index ebee8dd..582fa69 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -3,12 +3,14 @@ targetName = "Lua 5.3" -- Unsuported features tags.AttributeId = (t) if t[2] then - error("target does not support variable attributes") + error("target "..targetName.." does not support variable attributes") else return t[1] end end +#placeholder("patch") + #local patch = output #output = "" #import("compiler.lua54", { patch = patch, loadPackage = false }) diff --git a/compiler/luajit.can b/compiler/luajit.can index 9428fc5..511f642 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -3,13 +3,7 @@ targetName = "LuaJIT" UNPACK = (list, i, j) return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" end -APPEND = (t, toAppend) - return "do" .. indent() .. "local "..var("a")..", "..var("p").." = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #"..var("a").." do" .. indent() .. t .. "["..var("p").."] = "..var("a").."[i]" .. newline() .. ""..var("p").." = "..var("p").." + 1" .. unindent() .. "end" .. unindent() .. "end" -end -tags._opid.idiv = (left, right) - return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -end tags._opid.band = (left, right) addRequire("bit", "band", "band") return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" @@ -39,6 +33,6 @@ end #local patch = output #output = "" -#import("compiler.lua53", { patch = patch, loadPackage = false }) +#import("compiler.lua52", { patch = patch, loadPackage = false }) -return lua53 +return lua52 From 24a3e0ed6938f0d597d0be2c4c83d20015651fd0 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 17:26:57 +0100 Subject: [PATCH 21/52] Update README --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b74a2eb..47b6e95 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Candran ======= -Candran is a dialect of the [Lua 5.4](http://www.lua.org) programming language which compiles to Lua 5.4, Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. +Candran is a dialect of the [Lua 5.4](http://www.lua.org) programming language which compiles to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. @@ -188,8 +188,6 @@ const x, y, z = 1, 2, 3 -- every variable will be defined using Shortcut to Lua 5.4 variable attribute. Do not behave like `let`, as attributes require the variable to be constant and therefore can't be predeclared. -_Not in the latest release._ - ##### `continue` keyword ```lua for i=1, 10 do @@ -451,9 +449,9 @@ The preprocessor has access to the following variables: Compile targets --------------- -Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, LuaJIT, and Lua 5.1 compatible code. +Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT, and Lua 5.1 compatible code. -To chose a compile target, set the ```target``` option to ```lua54```, ```lua53```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. +To chose a compile target, set the ```target``` option to ```lua54```, ```lua53```, ```lua52```, ```luajit```, or ```lua51``` in the option table when using the library or the command line tools. Candran will try to detect the currently used Lua version and use it as the default target. Candran will try to translate Lua 5.4 syntax into something usable with the current target if possible. Here is what is currently supported: @@ -461,8 +459,9 @@ Candran will try to translate Lua 5.4 syntax into something usable with the curr | --- | --- | --- | --- | --- | --- | | Lua 5.4 | lua54 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Lua 5.3 | lua53 | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | -| LuaJIT | luajit | :white_check_mark: | :white_check_mark: | :white_check_mark: | X | -| Lua 5.2/5.1 | lua51 | :white_check_mark: | :white_check_mark: if LuaJIT bit library is available | X | X | +| Lua 5.2 | lua52 | :white_check_mark: | :white_check_mark: (32bit) | :white_check_mark: | X | +| LuaJIT | luajit | :white_check_mark: | :white_check_mark: (32bit) | :white_check_mark: | X | +| Lua 5.1 | lua51 | :white_check_mark: | :white_check_mark: if LuaJIT bit library is available (32bit) | X | X | **Please note** that Candran only translates syntax, and will not try to do anything about changes in the Lua standard library (for example, the new utf8 module). If you need this, you should be able to use [lua-compat-5.3](https://github.com/keplerproject/lua-compat-5.3) along with Candran. @@ -612,7 +611,7 @@ at the top of your main Lua file. If a Candran file is found when you call ```re You can give arbitrary options to the compiler and preprocessor, but Candran already provide and uses these with their associated default values: ```lua -target = "lua53" -- compiler target. "lua53", "luajit" or "lua51" (default is automatically selected based on the Lua version used). +target = "lua53" -- compiler target. "lua53", "lua52", "luajit" or "lua51" (default is automatically selected based on the Lua version used). indentation = "" -- character(s) used for indentation in the compiled file. newline = "\n" -- character(s) used for newlines in the compiled file. variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local variable to provide some functionality (example: to load LuaJIT's bit lib when using bitwise operators). From 98efdc95f480105b4298e2bd2f549536bc037e7a Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 18:17:27 +0100 Subject: [PATCH 22/52] Improve cancheck column detection for identifiers --- bin/cancheck | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bin/cancheck b/bin/cancheck index 61cc964..d9d3dcc 100644 --- a/bin/cancheck +++ b/bin/cancheck @@ -99,6 +99,13 @@ local function check(can) end end + -- Errors codes highlighting a identifier (alphanumeric+underscore not starting with a number): + -- 1xx: global variables + -- 2xx: unused variables + -- 3xx: unused values + -- 4xx: shadowing delarations + local isIdentifier = tonumber(warning.code) >= 100 and tonumber(warning.code) < 500 + -- calculating candran column local can_line = can_lines[warning.can_line] local lua_token = lua_line:sub(warning.column, warning.end_column) @@ -125,6 +132,14 @@ local function check(can) start, stop = nstart, nstop end end + -- for non aliases token that are identifier, check if match is a full identifier + -- (avoid things like `let e` matching the e in let) + elseif start and isIdentifier then + local prev = can_line:sub(start-1, start-1) + local next = can_line:sub(stop, stop) + if prev:match("[%w_]") or next:match("[%w_]") then + can_n = can_n - 1 -- skip this match + end end -- found if start then From d68c6fab0d1b377b8d1fe08d8b4aa7827768a872 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 24 Dec 2020 18:18:11 +0100 Subject: [PATCH 23/52] Candran v0.13 --- candran.can | 2 +- candran.lua | 2 +- ...{candran-0.12.0-1.rockspec => candran-0.13.0-1.rockspec} | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename rockspec/{candran-0.12.0-1.rockspec => candran-0.13.0-1.rockspec} (72%) diff --git a/candran.can b/candran.can index a80cf91..995a01d 100644 --- a/candran.can +++ b/candran.can @@ -15,7 +15,7 @@ local unpack = unpack or table.unpack local candran = { - VERSION = "0.13.1" + VERSION = "0.13.0" } --- Default options. diff --git a/candran.lua b/candran.lua index 28e491e..fa5cca6 100644 --- a/candran.lua +++ b/candran.lua @@ -6398,7 +6398,7 @@ end -- ./candran/can-parser/parser.lua:777 local parser = _() or parser -- ./candran/can-parser/parser.lua:781 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 local unpack = unpack or table["unpack"] -- candran.can:15 -local candran = { ["VERSION"] = "0.13.1" } -- candran.can:18 +local candran = { ["VERSION"] = "0.13.0" } -- candran.can:18 candran["default"] = { -- candran.can:22 ["target"] = "lua54", -- candran.can:23 ["indentation"] = "", -- candran.can:24 diff --git a/rockspec/candran-0.12.0-1.rockspec b/rockspec/candran-0.13.0-1.rockspec similarity index 72% rename from rockspec/candran-0.12.0-1.rockspec rename to rockspec/candran-0.13.0-1.rockspec index 6e2588d..1df15eb 100644 --- a/rockspec/candran-0.12.0-1.rockspec +++ b/rockspec/candran-0.13.0-1.rockspec @@ -2,12 +2,12 @@ rockspec_format = "3.0" package = "candran" -version = "0.12.0-1" +version = "0.13.0-1" description = { summary = "A simple Lua dialect and preprocessor.", detailed = [[ - Candran is a dialect of the Lua 5.3 programming language which compiles to Lua 5.3, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. + Candran is a dialect of the Lua 5.4 programming language which compiles to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT and Lua 5.1 compatible code. It adds several useful syntax additions which aims to make Lua faster and easier to write, and a simple preprocessor. Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code should be able to run on Candran unmodified. ]], license = "MIT", @@ -19,7 +19,7 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.12.0" + tag = "v0.13.0" } dependencies = { From 81f5f8fbbb554a309f57edbb68767591226e7df2 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 13:59:37 +0200 Subject: [PATCH 24/52] Improve error handling --- bin/can | 14 +- candran.can | 47 +++-- candran.lua | 492 +++++++++++++++++++++++++++------------------------- 3 files changed, 296 insertions(+), 257 deletions(-) diff --git a/bin/can b/bin/can index a960e00..cad0270 100644 --- a/bin/can +++ b/bin/can @@ -1,6 +1,6 @@ #!/usr/bin/env lua -local candran = require("candran") +local candran = require("candran").setup() local cmdline = require("candran.cmdline") local args = cmdline(arg) @@ -27,7 +27,11 @@ if arg[#arg] == "-" then io.stderr:write("can: "..err.."\n") os.exit(1) end - f() + local r, e = xpcall(f, candran.messageHandler) + if not r then + io.stderr:write(e.."\n") + os.exit(1) + end -- file elseif #args >= 1 then local f, err = candran.loadfile(args[1], nil, args) @@ -35,7 +39,11 @@ elseif #args >= 1 then io.stderr:write("can: "..err.."\n") os.exit(1) else - f() + local r, e = xpcall(f, candran.messageHandler) + if not r then + io.stderr:write(e.."\n") + os.exit(1) + end end -- REPL else diff --git a/candran.can b/candran.can index 995a01d..95700a8 100644 --- a/candran.can +++ b/candran.can @@ -15,8 +15,9 @@ local unpack = unpack or table.unpack local candran = { - VERSION = "0.13.0" + VERSION = "0.14.0" } +package.loaded["candran"] = candran --- Default options. candran.default = { @@ -221,7 +222,8 @@ function candran.load(chunk, chunkname, env, options={}) end codeCache[options.chunkname] = code - local f, err = util.load(code, options.chunkname, env) + local f + f, err = util.load(code, "=%s(%s)":format(options.chunkname, "compiled candran"), env) -- Um. Candran isn't supposed to generate invalid Lua code, so this is a major issue. -- This is not going to raise an error because this is supposed to behave similarly to Lua's load function. @@ -234,10 +236,9 @@ function candran.load(chunk, chunkname, env, options={}) return f else return function(...) - local params = {...} if not errorRewritingActive then errorRewritingActive = true - local t = { xpcall(() return f(unpack(params)) end, candran.messageHandler) } + local t = { xpcall(f, candran.messageHandler, ...) } errorRewritingActive = false if t[1] == false then error(t[2], 0) @@ -265,19 +266,21 @@ end --- Candran error message handler. -- Use it in xpcall to rewrite stacktraces to display Candran source file lines instead of compiled Lua lines. function candran.messageHandler(message) - return debug.traceback(message, 2):gsub("(\n?%s*)([^\n]-)%:(%d+)%:", function(indentation, source, line) + if not message:match("\nstack traceback:\n") then + message = debug.traceback(message, 2) + end + return message:gsub("(\n?%s*)([^\n]-)%:(%d+)%:", function(indentation, source, line) line = tonumber(line) local originalFile - local strName = source:match("%[string \"(.-)\"%]") + local strName = source:match("^(.-)%(compiled candran%)$") if strName then if codeCache[strName] then originalFile = codeCache[strName] source = strName end else - local fi = io.open(source, "r") - if fi then + if fi = io.open(source, "r") then originalFile = fi:read("*a") fi:close() end @@ -313,21 +316,31 @@ function candran.searcher(modpath) return "\n\tno candran file in package.path" end end - local r, s = candran.loadfile(filepath) - if r then - return r - else - return s - end + return () + local r, s = candran.loadfile(filepath) + if r then + return r() + else + error("error loading candran module '%s' from file '%s':\n\t%s":format(modpath, filepath, s), 0) + end + end, filepath end --- Register the Candran package searcher. function candran.setup() - if _VERSION == "Lua 5.1" then - table.insert(package.loaders, 2, candran.searcher) + local searchers = if _VERSION == "Lua 5.1" then + package.loaders else - table.insert(package.searchers, 2, candran.searcher) + package.searchers end + -- check if already setup + for _, s in ipairs(searchers) do + if s == candran.searcher then + return candran + end + end + -- setup + table.insert(searchers, 2, candran.searcher) return candran end diff --git a/candran.lua b/candran.lua index fa5cca6..14357bd 100644 --- a/candran.lua +++ b/candran.lua @@ -6398,259 +6398,277 @@ end -- ./candran/can-parser/parser.lua:777 local parser = _() or parser -- ./candran/can-parser/parser.lua:781 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 local unpack = unpack or table["unpack"] -- candran.can:15 -local candran = { ["VERSION"] = "0.13.0" } -- candran.can:18 -candran["default"] = { -- candran.can:22 -["target"] = "lua54", -- candran.can:23 -["indentation"] = "", -- candran.can:24 +local candran = { ["VERSION"] = "0.14.0" } -- candran.can:18 +package["loaded"]["candran"] = candran -- candran.can:20 +candran["default"] = { -- candran.can:23 +["target"] = "lua54", -- candran.can:24 +["indentation"] = "", -- candran.can:25 ["newline"] = "\ -", -- candran.can:25 -["variablePrefix"] = "__CAN_", -- candran.can:26 -["mapLines"] = true, -- candran.can:27 -["chunkname"] = "nil", -- candran.can:28 -["rewriteErrors"] = true -- candran.can:29 -} -- candran.can:29 -if _VERSION == "Lua 5.1" then -- candran.can:33 -if package["loaded"]["jit"] then -- candran.can:34 -candran["default"]["target"] = "luajit" -- candran.can:35 -else -- candran.can:35 -candran["default"]["target"] = "lua51" -- candran.can:37 -end -- candran.can:37 -elseif _VERSION == "Lua 5.2" then -- candran.can:39 -candran["default"]["target"] = "lua52" -- candran.can:40 -elseif _VERSION == "Lua 5.3" then -- candran.can:41 -candran["default"]["target"] = "lua53" -- candran.can:42 -end -- candran.can:42 -candran["preprocess"] = function(input, options) -- candran.can:51 -if options == nil then options = {} end -- candran.can:51 -options = util["merge"](candran["default"], options) -- candran.can:52 -local preprocessor = "" -- candran.can:55 -local i = 0 -- candran.can:56 -local inLongString = false -- candran.can:57 -local inComment = false -- candran.can:58 +", -- candran.can:26 +["variablePrefix"] = "__CAN_", -- candran.can:27 +["mapLines"] = true, -- candran.can:28 +["chunkname"] = "nil", -- candran.can:29 +["rewriteErrors"] = true -- candran.can:30 +} -- candran.can:30 +if _VERSION == "Lua 5.1" then -- candran.can:34 +if package["loaded"]["jit"] then -- candran.can:35 +candran["default"]["target"] = "luajit" -- candran.can:36 +else -- candran.can:36 +candran["default"]["target"] = "lua51" -- candran.can:38 +end -- candran.can:38 +elseif _VERSION == "Lua 5.2" then -- candran.can:40 +candran["default"]["target"] = "lua52" -- candran.can:41 +elseif _VERSION == "Lua 5.3" then -- candran.can:42 +candran["default"]["target"] = "lua53" -- candran.can:43 +end -- candran.can:43 +candran["preprocess"] = function(input, options) -- candran.can:52 +if options == nil then options = {} end -- candran.can:52 +options = util["merge"](candran["default"], options) -- candran.can:53 +local preprocessor = "" -- candran.can:56 +local i = 0 -- candran.can:57 +local inLongString = false -- candran.can:58 +local inComment = false -- candran.can:59 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:59 -i = i + (1) -- candran.can:60 -if inComment then -- candran.can:62 -inComment = not line:match("%]%]") -- candran.can:63 -elseif inLongString then -- candran.can:64 -inLongString = not line:match("%]%]") -- candran.can:65 -else -- candran.can:65 -if line:match("[^%-]%[%[") then -- candran.can:67 -inLongString = true -- candran.can:68 -elseif line:match("%-%-%[%[") then -- candran.can:69 -inComment = true -- candran.can:70 -end -- candran.can:70 -end -- candran.can:70 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:73 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:74 -else -- candran.can:74 -local l = line:sub(1, - 2) -- candran.can:76 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:77 +)") do -- candran.can:60 +i = i + (1) -- candran.can:61 +if inComment then -- candran.can:63 +inComment = not line:match("%]%]") -- candran.can:64 +elseif inLongString then -- candran.can:65 +inLongString = not line:match("%]%]") -- candran.can:66 +else -- candran.can:66 +if line:match("[^%-]%[%[") then -- candran.can:68 +inLongString = true -- candran.can:69 +elseif line:match("%-%-%[%[") then -- candran.can:70 +inComment = true -- candran.can:71 +end -- candran.can:71 +end -- candran.can:71 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:74 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:75 +else -- candran.can:75 +local l = line:sub(1, - 2) -- candran.can:77 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:78 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:78 -else -- candran.can:78 +") -- candran.can:79 +else -- candran.can:79 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:80 -end -- candran.can:80 -end -- candran.can:80 -end -- candran.can:80 -preprocessor = preprocessor .. ("return output") -- candran.can:84 -local env = util["merge"](_G, options) -- candran.can:87 -env["candran"] = candran -- candran.can:89 -env["output"] = "" -- candran.can:91 -env["import"] = function(modpath, margs) -- candran.can:98 -if margs == nil then margs = {} end -- candran.can:98 -local filepath = assert(util["search"](modpath, { -- candran.can:99 -"can", -- candran.can:99 -"lua" -- candran.can:99 -}), "No module named \"" .. modpath .. "\"") -- candran.can:99 -local f = io["open"](filepath) -- candran.can:102 -if not f then -- candran.can:103 -error("can't open the module file to import") -- candran.can:103 -end -- candran.can:103 -margs = util["merge"](options, { -- candran.can:105 -["chunkname"] = filepath, -- candran.can:105 -["loadLocal"] = true, -- candran.can:105 -["loadPackage"] = true -- candran.can:105 -}, margs) -- candran.can:105 -local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:106 -f:close() -- candran.can:107 -local modname = modpath:match("[^%.]+$") -- candran.can:110 +") -- candran.can:81 +end -- candran.can:81 +end -- candran.can:81 +end -- candran.can:81 +preprocessor = preprocessor .. ("return output") -- candran.can:85 +local env = util["merge"](_G, options) -- candran.can:88 +env["candran"] = candran -- candran.can:90 +env["output"] = "" -- candran.can:92 +env["import"] = function(modpath, margs) -- candran.can:99 +if margs == nil then margs = {} end -- candran.can:99 +local filepath = assert(util["search"](modpath, { -- candran.can:100 +"can", -- candran.can:100 +"lua" -- candran.can:100 +}), "No module named \"" .. modpath .. "\"") -- candran.can:100 +local f = io["open"](filepath) -- candran.can:103 +if not f then -- candran.can:104 +error("can't open the module file to import") -- candran.can:104 +end -- candran.can:104 +margs = util["merge"](options, { -- candran.can:106 +["chunkname"] = filepath, -- candran.can:106 +["loadLocal"] = true, -- candran.can:106 +["loadPackage"] = true -- candran.can:106 +}, margs) -- candran.can:106 +local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:107 +f:close() -- candran.can:108 +local modname = modpath:match("[^%.]+$") -- candran.can:111 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:119 -end -- candran.can:119 -env["include"] = function(file) -- candran.can:124 -local f = io["open"](file) -- candran.can:125 -if not f then -- candran.can:126 -error("can't open the file " .. file .. " to include") -- candran.can:126 -end -- candran.can:126 -env["write"](f:read("*a")) -- candran.can:127 -f:close() -- candran.can:128 -end -- candran.can:128 -env["write"] = function(...) -- candran.can:132 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:120 +end -- candran.can:120 +env["include"] = function(file) -- candran.can:125 +local f = io["open"](file) -- candran.can:126 +if not f then -- candran.can:127 +error("can't open the file " .. file .. " to include") -- candran.can:127 +end -- candran.can:127 +env["write"](f:read("*a")) -- candran.can:128 +f:close() -- candran.can:129 +end -- candran.can:129 +env["write"] = function(...) -- candran.can:133 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:133 -end -- candran.can:133 -env["placeholder"] = function(name) -- candran.can:137 -if env[name] then -- candran.can:138 -env["write"](env[name]) -- candran.can:139 -end -- candran.can:139 -end -- candran.can:139 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:144 -if not preprocess then -- candran.can:145 -return nil, "in preprocessor: " .. err -- candran.can:146 -end -- candran.can:146 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:149 -if not preprocess then -- candran.can:150 -return nil, "in preprocessor: " .. err -- candran.can:151 -end -- candran.can:151 -local success, output = pcall(preprocess) -- candran.can:155 -if not success then -- candran.can:156 -return nil, "in preprocessor: " .. output -- candran.can:157 -end -- candran.can:157 -return output -- candran.can:160 -end -- candran.can:160 -candran["compile"] = function(input, options) -- candran.can:169 -if options == nil then options = {} end -- candran.can:169 -options = util["merge"](candran["default"], options) -- candran.can:170 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:172 -if not ast then -- candran.can:174 -return nil, errmsg -- candran.can:175 -end -- candran.can:175 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:178 -end -- candran.can:178 -candran["make"] = function(code, options) -- candran.can:187 -local r, err = candran["preprocess"](code, options) -- candran.can:188 -if r then -- candran.can:189 -r, err = candran["compile"](r, options) -- candran.can:190 -if r then -- candran.can:191 -return r -- candran.can:192 -end -- candran.can:192 -end -- candran.can:192 -return r, err -- candran.can:195 -end -- candran.can:195 -local errorRewritingActive = false -- candran.can:198 -local codeCache = {} -- candran.can:199 -candran["loadfile"] = function(filepath, env, options) -- candran.can:202 -local f, err = io["open"](filepath) -- candran.can:203 -if not f then -- candran.can:204 -return nil, ("cannot open %s"):format(err) -- candran.can:205 -end -- candran.can:205 -local content = f:read("*a") -- candran.can:207 -f:close() -- candran.can:208 -return candran["load"](content, filepath, env, options) -- candran.can:210 -end -- candran.can:210 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:215 -if options == nil then options = {} end -- candran.can:215 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:216 -local code, err = candran["make"](chunk, options) -- candran.can:218 -if not code then -- candran.can:219 -return code, err -- candran.can:220 -end -- candran.can:220 -codeCache[options["chunkname"]] = code -- candran.can:223 -local f, err = util["load"](code, options["chunkname"], env) -- candran.can:224 -if f == nil then -- candran.can:229 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:230 -end -- candran.can:230 -if options["rewriteErrors"] == false then -- candran.can:233 -return f -- candran.can:234 -else -- candran.can:234 -return function(...) -- candran.can:236 -local params = { ... } -- candran.can:237 -if not errorRewritingActive then -- candran.can:238 -errorRewritingActive = true -- candran.can:239 -local t = { xpcall(function() -- candran.can:240 -return f(unpack(params)) -- candran.can:240 -end, candran["messageHandler"]) } -- candran.can:240 -errorRewritingActive = false -- candran.can:241 -if t[1] == false then -- candran.can:242 -error(t[2], 0) -- candran.can:243 -end -- candran.can:243 -return unpack(t, 2) -- candran.can:245 -else -- candran.can:245 -return f(...) -- candran.can:247 -end -- candran.can:247 -end -- candran.can:247 -end -- candran.can:247 -end -- candran.can:247 -candran["dofile"] = function(filename, options) -- candran.can:255 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:256 -if f == nil then -- candran.can:258 -error(err) -- candran.can:259 -else -- candran.can:259 -return f() -- candran.can:261 -end -- candran.can:261 -end -- candran.can:261 -candran["messageHandler"] = function(message) -- candran.can:267 -return debug["traceback"](message, 2):gsub("(\ +") -- candran.can:134 +end -- candran.can:134 +env["placeholder"] = function(name) -- candran.can:138 +if env[name] then -- candran.can:139 +env["write"](env[name]) -- candran.can:140 +end -- candran.can:140 +end -- candran.can:140 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:145 +if not preprocess then -- candran.can:146 +return nil, "in preprocessor: " .. err -- candran.can:147 +end -- candran.can:147 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:150 +if not preprocess then -- candran.can:151 +return nil, "in preprocessor: " .. err -- candran.can:152 +end -- candran.can:152 +local success, output = pcall(preprocess) -- candran.can:156 +if not success then -- candran.can:157 +return nil, "in preprocessor: " .. output -- candran.can:158 +end -- candran.can:158 +return output -- candran.can:161 +end -- candran.can:161 +candran["compile"] = function(input, options) -- candran.can:170 +if options == nil then options = {} end -- candran.can:170 +options = util["merge"](candran["default"], options) -- candran.can:171 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:173 +if not ast then -- candran.can:175 +return nil, errmsg -- candran.can:176 +end -- candran.can:176 +return require("compiler." .. options["target"])(input, ast, options) -- candran.can:179 +end -- candran.can:179 +candran["make"] = function(code, options) -- candran.can:188 +local r, err = candran["preprocess"](code, options) -- candran.can:189 +if r then -- candran.can:190 +r, err = candran["compile"](r, options) -- candran.can:191 +if r then -- candran.can:192 +return r -- candran.can:193 +end -- candran.can:193 +end -- candran.can:193 +return r, err -- candran.can:196 +end -- candran.can:196 +local errorRewritingActive = false -- candran.can:199 +local codeCache = {} -- candran.can:200 +candran["loadfile"] = function(filepath, env, options) -- candran.can:203 +local f, err = io["open"](filepath) -- candran.can:204 +if not f then -- candran.can:205 +return nil, ("cannot open %s"):format(err) -- candran.can:206 +end -- candran.can:206 +local content = f:read("*a") -- candran.can:208 +f:close() -- candran.can:209 +return candran["load"](content, filepath, env, options) -- candran.can:211 +end -- candran.can:211 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:216 +if options == nil then options = {} end -- candran.can:216 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:217 +local code, err = candran["make"](chunk, options) -- candran.can:219 +if not code then -- candran.can:220 +return code, err -- candran.can:221 +end -- candran.can:221 +codeCache[options["chunkname"]] = code -- candran.can:224 +local f -- candran.can:225 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:226 +if f == nil then -- candran.can:231 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:232 +end -- candran.can:232 +if options["rewriteErrors"] == false then -- candran.can:235 +return f -- candran.can:236 +else -- candran.can:236 +return function(...) -- candran.can:238 +if not errorRewritingActive then -- candran.can:239 +errorRewritingActive = true -- candran.can:240 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:241 +errorRewritingActive = false -- candran.can:242 +if t[1] == false then -- candran.can:243 +error(t[2], 0) -- candran.can:244 +end -- candran.can:244 +return unpack(t, 2) -- candran.can:246 +else -- candran.can:246 +return f(...) -- candran.can:248 +end -- candran.can:248 +end -- candran.can:248 +end -- candran.can:248 +end -- candran.can:248 +candran["dofile"] = function(filename, options) -- candran.can:256 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:257 +if f == nil then -- candran.can:259 +error(err) -- candran.can:260 +else -- candran.can:260 +return f() -- candran.can:262 +end -- candran.can:262 +end -- candran.can:262 +candran["messageHandler"] = function(message) -- candran.can:268 +if not message:match("\ +stack traceback:\ +") then -- candran.can:269 +message = debug["traceback"](message, 2) -- candran.can:270 +end -- candran.can:270 +return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:268 -line = tonumber(line) -- candran.can:269 -local originalFile -- candran.can:271 -local strName = source:match("%[string \"(.-)\"%]") -- candran.can:272 -if strName then -- candran.can:273 -if codeCache[strName] then -- candran.can:274 -originalFile = codeCache[strName] -- candran.can:275 -source = strName -- candran.can:276 -end -- candran.can:276 -else -- candran.can:276 -local fi = io["open"](source, "r") -- candran.can:279 -if fi then -- candran.can:280 -originalFile = fi:read("*a") -- candran.can:281 -fi:close() -- candran.can:282 -end -- candran.can:282 -end -- candran.can:282 -if originalFile then -- candran.can:286 -local i = 0 -- candran.can:287 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:272 +line = tonumber(line) -- candran.can:273 +local originalFile -- candran.can:275 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:276 +if strName then -- candran.can:277 +if codeCache[strName] then -- candran.can:278 +originalFile = codeCache[strName] -- candran.can:279 +source = strName -- candran.can:280 +end -- candran.can:280 +else -- candran.can:280 +do -- candran.can:283 +local fi -- candran.can:283 +fi = io["open"](source, "r") -- candran.can:283 +if fi then -- candran.can:283 +originalFile = fi:read("*a") -- candran.can:284 +fi:close() -- candran.can:285 +end -- candran.can:285 +end -- candran.can:285 +end -- candran.can:285 +if originalFile then -- candran.can:289 +local i = 0 -- candran.can:290 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:288 -i = i + 1 -- candran.can:289 -if i == line then -- candran.can:290 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:291 -if lineMap then -- candran.can:292 -if extSource ~= source then -- candran.can:293 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:294 -else -- candran.can:294 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:296 -end -- candran.can:296 -end -- candran.can:296 -break -- candran.can:299 +") do -- candran.can:291 +i = i + 1 -- candran.can:292 +if i == line then -- candran.can:293 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:294 +if lineMap then -- candran.can:295 +if extSource ~= source then -- candran.can:296 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:297 +else -- candran.can:297 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:299 end -- candran.can:299 end -- candran.can:299 -end -- candran.can:299 -end) -- candran.can:299 -end -- candran.can:299 -candran["searcher"] = function(modpath) -- candran.can:307 -local filepath = util["search"](modpath, { "can" }) -- candran.can:308 -if not filepath then -- candran.can:309 -if _VERSION == "Lua 5.4" then -- candran.can:310 -return "no candran file in package.path" -- candran.can:311 -else -- candran.can:311 +break -- candran.can:302 +end -- candran.can:302 +end -- candran.can:302 +end -- candran.can:302 +end) -- candran.can:302 +end -- candran.can:302 +candran["searcher"] = function(modpath) -- candran.can:310 +local filepath = util["search"](modpath, { "can" }) -- candran.can:311 +if not filepath then -- candran.can:312 +if _VERSION == "Lua 5.4" then -- candran.can:313 +return "no candran file in package.path" -- candran.can:314 +else -- candran.can:314 return "\ -\9no candran file in package.path" -- candran.can:313 -end -- candran.can:313 -end -- candran.can:313 -local r, s = candran["loadfile"](filepath) -- candran.can:316 -if r then -- candran.can:317 -return r -- candran.can:318 -else -- candran.can:318 -return s -- candran.can:320 -end -- candran.can:320 -end -- candran.can:320 -candran["setup"] = function() -- candran.can:325 -if _VERSION == "Lua 5.1" then -- candran.can:326 -table["insert"](package["loaders"], 2, candran["searcher"]) -- candran.can:327 -else -- candran.can:327 -table["insert"](package["searchers"], 2, candran["searcher"]) -- candran.can:329 -end -- candran.can:329 -return candran -- candran.can:331 -end -- candran.can:331 -return candran -- candran.can:334 +\9no candran file in package.path" -- candran.can:316 +end -- candran.can:316 +end -- candran.can:316 +return function() -- candran.can:319 +local r, s = candran["loadfile"](filepath) -- candran.can:320 +if r then -- candran.can:321 +return r() -- candran.can:322 +else -- candran.can:322 +error(("error loading candran module '%s' from file '%s':\ +\9%s"):format(modpath, filepath, s), 0) -- candran.can:324 +end -- candran.can:324 +end, filepath -- candran.can:326 +end -- candran.can:326 +candran["setup"] = function() -- candran.can:330 +local searchers = (function() -- candran.can:331 +if _VERSION == "Lua 5.1" then -- candran.can:331 +return package["loaders"] -- candran.can:332 +else -- candran.can:332 +return package["searchers"] -- candran.can:334 +end -- candran.can:334 +end)() -- candran.can:334 +for _, s in ipairs(searchers) do -- candran.can:337 +if s == candran["searcher"] then -- candran.can:338 +return candran -- candran.can:339 +end -- candran.can:339 +end -- candran.can:339 +table["insert"](searchers, 2, candran["searcher"]) -- candran.can:343 +return candran -- candran.can:344 +end -- candran.can:344 +return candran -- candran.can:347 From b00068c766186517c89a3d5cad7c3bea5eaeb62b Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 14:21:14 +0200 Subject: [PATCH 25/52] Load candran before lua files --- candran.can | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/candran.can b/candran.can index 95700a8..e5fbefa 100644 --- a/candran.can +++ b/candran.can @@ -340,7 +340,7 @@ function candran.setup() end end -- setup - table.insert(searchers, 2, candran.searcher) + table.insert(searchers, 1, candran.searcher) return candran end From d65c11e8d9b7a400dd62635c30da3bac4b968d36 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 14:29:08 +0200 Subject: [PATCH 26/52] Fix Candran loader --- candran.can | 4 ++-- candran.lua | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/candran.can b/candran.can index e5fbefa..3b433ac 100644 --- a/candran.can +++ b/candran.can @@ -316,10 +316,10 @@ function candran.searcher(modpath) return "\n\tno candran file in package.path" end end - return () + return (modpath) -- 2nd argument is not passed in Lua 5.1, so a closure is required local r, s = candran.loadfile(filepath) if r then - return r() + return r(modpath, filepath) else error("error loading candran module '%s' from file '%s':\n\t%s":format(modpath, filepath, s), 0) end diff --git a/candran.lua b/candran.lua index 14357bd..514e2d8 100644 --- a/candran.lua +++ b/candran.lua @@ -6347,10 +6347,10 @@ end + P("--") * (P(1) - P("\ ["ShortStr"] = P("\"") * Cs((V("EscSeq") + (P(1) - S("\"\ "))) ^ 0) * expect(P("\""), "Quote") + P("'") * Cs((V("EscSeq") + (P(1) - S("'\ "))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:693 -["EscSeq"] = P("\\") / "" * (P("a") / "\7" + P("b") / "\8" + P("f") / "\12" + P("n") / "\ -" + P("r") / "\13" + P("t") / "\9" + P("v") / "\11" + P("\ +["EscSeq"] = P("\\") / "" * (P("a") / "" + P("b") / "" + P("f") / " " + P("n") / "\ +" + P("r") / "\r" + P("t") / " " + P("v") / " " + P("\ ") / "\ -" + P("\13") / "\ +" + P("\r") / "\ " + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:723 ["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:726 return s -- ./candran/can-parser/parser.lua:726 @@ -6495,7 +6495,7 @@ env["write"](f:read("*a")) -- candran.can:128 f:close() -- candran.can:129 end -- candran.can:129 env["write"] = function(...) -- candran.can:133 -env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ +env["output"] = env["output"] .. (table["concat"]({ ... }, " ") .. "\ ") -- candran.can:134 end -- candran.can:134 env["placeholder"] = function(name) -- candran.can:138 @@ -6642,16 +6642,16 @@ if _VERSION == "Lua 5.4" then -- candran.can:313 return "no candran file in package.path" -- candran.can:314 else -- candran.can:314 return "\ -\9no candran file in package.path" -- candran.can:316 + no candran file in package.path" -- candran.can:316 end -- candran.can:316 end -- candran.can:316 -return function() -- candran.can:319 +return function(modpath) -- candran.can:319 local r, s = candran["loadfile"](filepath) -- candran.can:320 if r then -- candran.can:321 -return r() -- candran.can:322 +return r(modpath, filepath) -- candran.can:322 else -- candran.can:322 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, s), 0) -- candran.can:324 + %s"):format(modpath, filepath, s), 0) -- candran.can:324 end -- candran.can:324 end, filepath -- candran.can:326 end -- candran.can:326 @@ -6668,7 +6668,7 @@ if s == candran["searcher"] then -- candran.can:338 return candran -- candran.can:339 end -- candran.can:339 end -- candran.can:339 -table["insert"](searchers, 2, candran["searcher"]) -- candran.can:343 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:343 return candran -- candran.can:344 end -- candran.can:344 return candran -- candran.can:347 From a9dc5ab254aa39d8fc57855c2d8c43c3c32bb817 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 14:57:24 +0200 Subject: [PATCH 27/52] Update README --- README.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 47b6e95..a3ff232 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ local function calculate(toadd=25) -- default parameters end let a = { - hey = true, + hey = 5 // 2, -- Lua 5.3+ syntax, that will be translated to work with the current Lua version child = nil, @@ -82,6 +82,8 @@ You can optionally install lua-linenoise (```luarocks install linenoise```, vers You can register the Candran package searcher in your main Lua file (`require("candran").setup()`) and any subsequent `require` call in your project will automatically search for Candran modules. +If you use LÖVE, some integration with Candran is detailled [here](#https://github.com/Reuh/candran/wiki/L%C3%96VE). + #### Editor support Most editors should be able to use their existing Lua support for Candran code. If you want full support for the additional syntax in your editor: * **Sublime Text 3**: @@ -95,7 +97,7 @@ For linting, if your editor support [luacheck](https://github.com/luarocks/luach The language ------------ ### Syntax additions -After the preprocessor is run the Candran code is compiled to Lua. Candran code adds the folowing syntax to Lua: +After the [preprocessor](#preprocessor) is run the Candran code is compiled to Lua. Candran code adds the folowing syntax to Lua 5.4 syntax: ##### Assignment operators * ````var += nb```` @@ -186,7 +188,7 @@ close b = {} const x, y, z = 1, 2, 3 -- every variable will be defined using ``` -Shortcut to Lua 5.4 variable attribute. Do not behave like `let`, as attributes require the variable to be constant and therefore can't be predeclared. +Shortcut to Lua 5.4 variable attribute. Do not behave like `let`, as attributes require the variable to be constant and therefore can't be predeclared. Only compatibel with Lua 5.4 target. ##### `continue` keyword ```lua @@ -439,12 +441,14 @@ Will output ````print("Bonjour")```` or ````print("Hello")```` depending of the The preprocessor has access to the following variables: * ````candran````: the Candran library table. -* ````output````: the current preprocessor output string. Can be redefined at any time. -* ````import(module[, [options])````: a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: ```loadLocal``` (default ```true```): ```true``` to automatically load the module into a local variable (i.e. ```local thing = require("module.thing")```); ```loadPackage``` (default ```true```): ```true``` to automatically load the module into the loaded packages table (so it will be available for following ```require("module")``` calls). +* ````output````: the current preprocessor output string. Can be redefined at any time. If you want to write something in the preprocessor output, it is preferred to use `write(...)` instead of directly modifying `output`. +* ````import(module[, [options])````: a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: + * ```loadLocal``` (default ```true```): ```true``` to automatically load the module into a local variable (i.e. ```local thing = require("module.thing")```) + * ```loadPackage``` (default ```true```): ```true``` to automatically load the module into the loaded packages table (so it will be available for following ```require("module")``` calls). * ````include(filename)````: a function which copy the contents of the file _filename_ to the output. * ````write(...)````: write to the preprocessor output. For example, ````#write("hello()")```` will output ````hello()```` in the final file. * ```placeholder(name)```: if the variable _name_ is defined in the preprocessor environement, its content will be inserted here. -* ````...````: each arguments passed to the preprocessor is directly available in the environment. +* each arguments passed to the preprocessor is directly available in the environment. * and every standard Lua library. Compile targets @@ -468,7 +472,7 @@ Candran will try to translate Lua 5.4 syntax into something usable with the curr Usage ----- ### Command-line usage -The library can be used standalone through the ```canc``` and ```can``` utility: +The library can be used standalone through the ```canc``` (for compiling Candran files) and ```can``` (for running Candran files directly) utilities: * ````canc```` @@ -516,7 +520,7 @@ The library can be used standalone through the ```canc``` and ```can``` utility: * ```can``` - Start a simplisitic Candran REPL. + Start a simplisitic Candran REPL. Will automatically call `candran.setup()`. If you want a better REPL (autocompletion, history, ability to move the cursor), install lua-linenoise: ```luarocks install linenoise``` (automatically installed if Candran was installed using LuaRocks). @@ -524,7 +528,7 @@ The library can be used standalone through the ```canc``` and ```can``` utility: Preprocess, compile and run _filename_ using the options provided. - This will automatically register the Candran package searcher, so required Candran modules will be compiled as they are needed. + This will automatically register the Candran package searcher using `candran.setup()`, so required Candran modules will be compiled as they are needed. This command will use error rewriting unless explicitely enabled (by setting the `rewriteErrors=false` option). @@ -589,10 +593,14 @@ If you are using the preprocessor ```import()``` function, the source Candran fi example.can:12(final.lua:5): attempt to call a nil value (global 'iWantAnError') ``` -You can perform error rewriting manually using: +Please note that Candran can only wrap code directly called from Candran; if an error is raised from Lua, there will be no rewriting of Candran lines the stacktrace. These lines are indicated using `(compiled candran)` before the line number. + +If you want Candran to always wrap errors, you will need to wrap your whole code in a `xpcall`: `xpcall(func, candran.messageHandler)`. * ```candran.messageHandler(message)```: the error message handler used by Candran. Given `message` the Lua error string, returns full Candran traceback where soure files and lines are rewritten to their Candran source. You can use it as is in xpcall as a message handler. +Also note that the Candran message handler will add a new, rewritten, stacktrace to the error message; it can't replace the default Lua one. You will therefore see two stacktraces when raising an error, the last one being the Lua one and can be ignored. + ##### Package searching helpers Candran comes with a custom package searcher which will automatically find, preprocesses and compile ```.can``` files. @@ -605,7 +613,7 @@ require("candran").setup() at the top of your main Lua file. If a Candran file is found when you call ```require()```, it will be automatically compiled and loaded. If both a Lua and Candran file match a module name, the Candran file will be loaded. * ```candran.searcher(modpath)```: Candran package searcher function. Use the existing package.path. -* ```candran.setup()```: register the Candran package searcher, and return the `candran` table. +* ```candran.setup()```: register the Candran package searcher (if not already done), and return the `candran` table. ##### Available compiler & preprocessor options You can give arbitrary options to the compiler and preprocessor, but Candran already provide and uses these with their associated default values: From a3f05f50463d6933ef7143c0996ed21ddc91e0fd Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 14:57:34 +0200 Subject: [PATCH 28/52] Update year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e117f05..4b0a3df 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017-2019 Étienne "Reuh" Fildadut +Copyright (c) 2017-2021 Étienne "Reuh" Fildadut Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: From f5752cd2312f1c5344656e5044a997fbfdca473a Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 15:19:55 +0200 Subject: [PATCH 29/52] Allow rewriting without new traceback --- README.md | 2 +- candran.can | 4 ++-- candran.lua | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a3ff232..397d002 100644 --- a/README.md +++ b/README.md @@ -597,7 +597,7 @@ Please note that Candran can only wrap code directly called from Candran; if an If you want Candran to always wrap errors, you will need to wrap your whole code in a `xpcall`: `xpcall(func, candran.messageHandler)`. -* ```candran.messageHandler(message)```: the error message handler used by Candran. Given `message` the Lua error string, returns full Candran traceback where soure files and lines are rewritten to their Candran source. You can use it as is in xpcall as a message handler. +* ```candran.messageHandler(message[, noTraceback])```: the error message handler used by Candran. Given `message` the Lua error string, returns full Candran traceback where soure files and lines are rewritten to their Candran source. You can use it as is in xpcall as a message handler. If `noTraceback` is `true`, Candran will only rewrite `message` and not add a new traceback. Also note that the Candran message handler will add a new, rewritten, stacktrace to the error message; it can't replace the default Lua one. You will therefore see two stacktraces when raising an error, the last one being the Lua one and can be ignored. diff --git a/candran.can b/candran.can index 3b433ac..57f115d 100644 --- a/candran.can +++ b/candran.can @@ -265,8 +265,8 @@ end --- Candran error message handler. -- Use it in xpcall to rewrite stacktraces to display Candran source file lines instead of compiled Lua lines. -function candran.messageHandler(message) - if not message:match("\nstack traceback:\n") then +function candran.messageHandler(message, noTraceback) + if not noTraceback and not message:match("\nstack traceback:\n") then message = debug.traceback(message, 2) end return message:gsub("(\n?%s*)([^\n]-)%:(%d+)%:", function(indentation, source, line) diff --git a/candran.lua b/candran.lua index 514e2d8..51a26ad 100644 --- a/candran.lua +++ b/candran.lua @@ -6586,8 +6586,8 @@ else -- candran.can:260 return f() -- candran.can:262 end -- candran.can:262 end -- candran.can:262 -candran["messageHandler"] = function(message) -- candran.can:268 -if not message:match("\ +candran["messageHandler"] = function(message, noTraceback) -- candran.can:268 +if not noTraceback and not message:match("\ stack traceback:\ ") then -- candran.can:269 message = debug["traceback"](message, 2) -- candran.can:270 From 012b5c1d5aae25ca0edbf201b812559794d9bb72 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 15:29:54 +0200 Subject: [PATCH 30/52] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 397d002..abd7430 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ You can optionally install lua-linenoise (```luarocks install linenoise```, vers You can register the Candran package searcher in your main Lua file (`require("candran").setup()`) and any subsequent `require` call in your project will automatically search for Candran modules. -If you use LÖVE, some integration with Candran is detailled [here](#https://github.com/Reuh/candran/wiki/L%C3%96VE). +If you use LÖVE, some integration with Candran is detailled [here](https://github.com/Reuh/candran/wiki/L%C3%96VE). #### Editor support Most editors should be able to use their existing Lua support for Candran code. If you want full support for the additional syntax in your editor: From 66f1a5a3c261bde75308ca380545159bbaa534bf Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 17 May 2021 15:37:20 +0200 Subject: [PATCH 31/52] Candran v0.14 --- README.md | 2 +- .../{candran-0.13.0-1.rockspec => candran-0.14.0-1.rockspec} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename rockspec/{candran-0.13.0-1.rockspec => candran-0.14.0-1.rockspec} (96%) diff --git a/README.md b/README.md index abd7430..805972c 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ end Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup -Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.12.0-1.rockspec```. +Install Candran automatically using LuaRocks: ```sudo luarocks install candran```. Or manually install LPegLabel (```luarocks install lpeglabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. diff --git a/rockspec/candran-0.13.0-1.rockspec b/rockspec/candran-0.14.0-1.rockspec similarity index 96% rename from rockspec/candran-0.13.0-1.rockspec rename to rockspec/candran-0.14.0-1.rockspec index 1df15eb..dc82cd2 100644 --- a/rockspec/candran-0.13.0-1.rockspec +++ b/rockspec/candran-0.14.0-1.rockspec @@ -2,7 +2,7 @@ rockspec_format = "3.0" package = "candran" -version = "0.13.0-1" +version = "0.14.0-1" description = { summary = "A simple Lua dialect and preprocessor.", @@ -19,7 +19,7 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.13.0" + tag = "v0.14.0" } dependencies = { From ebd36d710326ef7fbaa33cf74e0a32f0dd53eaa5 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 7 Jun 2021 17:04:26 +0200 Subject: [PATCH 32/52] Add macro support in preprocessor --- candran.can | 41 +- candran.lua | 9876 +++++++++++++++++---------------- candran/can-parser/parser.lua | 32 +- candran/util.can | 14 + compiler/lua54.can | 56 +- test/test.lua | 48 + 6 files changed, 5304 insertions(+), 4763 deletions(-) diff --git a/candran.can b/candran.can index 57f115d..9e1d1fd 100644 --- a/candran.can +++ b/candran.can @@ -47,10 +47,15 @@ end -- @tparam input string input code -- @tparam options table arguments for the preprocessor. They will be inserted into the preprocessor environement. -- @treturn[1] output string output code +-- @treturn[1] macros registered macros -- @treturn[2] nil nil if error -- @treturn[2] error string error message function candran.preprocess(input, options={}) options = util.merge(candran.default, options) + local macros = { + functions = {}, + variables = {} + } -- generate preprocessor code local preprocessor = "" @@ -104,7 +109,8 @@ function candran.preprocess(input, options={}) if not f then error("can't open the module file to import") end margs = util.merge(options, { chunkname = filepath, loadLocal = true, loadPackage = true }, margs) - local modcontent = assert(candran.preprocess(f:read("*a"), margs)) + local modcontent, modmacros = assert(candran.preprocess(f:read("*a"), margs)) + macros = util.recmerge(macros, modmacros) f:close() -- get module name (ex: module name of path.to.module is module) @@ -140,6 +146,30 @@ function candran.preprocess(input, options={}) env.write(env[name]) end end + env.define = function(identifier, replacement) + -- parse identifier + local iast, ierr = parser.parsemacroidentifier(identifier, options.chunkname) + if not iast then + return error("in macro identifier: %s":format(ierr)) + end + -- parse replacement value + local rast, rerr = parser.parse(replacement, options.chunkname) + if not rast then + return error("in macro replacement: %s":format(rerr)) + end + -- when giving a single value as a replacement, bypass the implicit push + if #rast == 1 and rast[1].tag == "Push" and rast[1].implicit then + rast = rast[1][1] + end + -- add macros + if iast.tag == "MacroFunction" then + macros.functions[iast[1][1]] = { args = iast[2], replacement = rast } + elseif iast.tag == "Id" then + macros.variables[iast[1]] = rast + else + error("invalid macro type %s":format(iast.tag)) + end + end -- compile & load preprocessor local preprocess, err = candran.compile(preprocessor, options) @@ -158,16 +188,17 @@ function candran.preprocess(input, options={}) return nil, "in preprocessor: "..output end - return output + return output, macros end --- Run the compiler -- @tparam input string input code -- @tparam options table options for the compiler +-- @tparam macros table defined macros, as returned by the preprocessor -- @treturn[1] output string output code -- @treturn[2] nil nil if error -- @treturn[2] error string error message -function candran.compile(input, options={}) +function candran.compile(input, options={}, macros) options = util.merge(candran.default, options) local ast, errmsg = parser.parse(input, options.chunkname) @@ -176,7 +207,7 @@ function candran.compile(input, options={}) return nil, errmsg end - return require("compiler."..options.target)(input, ast, options) + return require("compiler."..options.target)(input, ast, options, macros) end --- Preprocess & compile code @@ -188,7 +219,7 @@ end function candran.make(code, options) local r, err = candran.preprocess(code, options) if r then - r, err = candran.compile(r, options) + r, err = candran.compile(r, options, err) if r then return r end diff --git a/candran.lua b/candran.lua index 51a26ad..fdcd523 100644 --- a/candran.lua +++ b/candran.lua @@ -28,20 +28,33 @@ return load(str, name) -- ./candran/util.can:25 end -- ./candran/util.can:25 end -- ./candran/util.can:25 end -- ./candran/util.can:25 -util["merge"] = function(...) -- ./candran/util.can:30 +util["recmerge"] = function(...) -- ./candran/util.can:30 local r = {} -- ./candran/util.can:31 for _, t in ipairs({ ... }) do -- ./candran/util.can:32 for k, v in pairs(t) do -- ./candran/util.can:33 -r[k] = v -- ./candran/util.can:34 -end -- ./candran/util.can:34 -end -- ./candran/util.can:34 -return r -- ./candran/util.can:37 +if type(v) == "table" then -- ./candran/util.can:34 +r[k] = util["merge"](v, r[k]) -- ./candran/util.can:35 +else -- ./candran/util.can:35 +r[k] = v -- ./candran/util.can:37 end -- ./candran/util.can:37 -return util -- ./candran/util.can:40 -end -- ./candran/util.can:40 -local util = _() or util -- ./candran/util.can:44 -package["loaded"]["candran.util"] = util or true -- ./candran/util.can:45 -local function _() -- ./candran/util.can:48 +end -- ./candran/util.can:37 +end -- ./candran/util.can:37 +return r -- ./candran/util.can:41 +end -- ./candran/util.can:41 +util["merge"] = function(...) -- ./candran/util.can:44 +local r = {} -- ./candran/util.can:45 +for _, t in ipairs({ ... }) do -- ./candran/util.can:46 +for k, v in pairs(t) do -- ./candran/util.can:47 +r[k] = v -- ./candran/util.can:48 +end -- ./candran/util.can:48 +end -- ./candran/util.can:48 +return r -- ./candran/util.can:51 +end -- ./candran/util.can:51 +return util -- ./candran/util.can:54 +end -- ./candran/util.can:54 +local util = _() or util -- ./candran/util.can:58 +package["loaded"]["candran.util"] = util or true -- ./candran/util.can:59 +local function _() -- ./candran/util.can:62 local ipairs, pairs, setfenv, tonumber, loadstring, type = ipairs, pairs, setfenv, tonumber, loadstring, type -- ./candran/cmdline.lua:5 local tinsert, tconcat = table["insert"], table["concat"] -- ./candran/cmdline.lua:6 local function commonerror(msg) -- ./candran/cmdline.lua:8 @@ -129,1724 +142,1844 @@ end -- ./candran/cmdline.lua:125 local cmdline = _() or cmdline -- ./candran/cmdline.lua:130 package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua:131 local function _() -- ./candran/cmdline.lua:135 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 -return function(code, ast, options) -- ./compiler/lua54.can:3 -local lastInputPos = 1 -- ./compiler/lua54.can:5 -local prevLinePos = 1 -- ./compiler/lua54.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 -local lastLine = 1 -- ./compiler/lua54.can:8 -local indentLevel = 0 -- ./compiler/lua54.can:11 -local function newline() -- ./compiler/lua54.can:13 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 -if options["mapLines"] then -- ./compiler/lua54.can:15 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local util = require("candran.util") -- ./compiler/lua54.can:1 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 +return function(code, ast, options, macros) -- ./compiler/lua54.can:5 +if macros == nil then macros = { -- ./compiler/lua54.can:5 +["functions"] = {}, -- ./compiler/lua54.can:5 +["variables"] = {} -- ./compiler/lua54.can:5 +} end -- ./compiler/lua54.can:5 +local lastInputPos = 1 -- ./compiler/lua54.can:7 +local prevLinePos = 1 -- ./compiler/lua54.can:8 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 +local lastLine = 1 -- ./compiler/lua54.can:10 +local indentLevel = 0 -- ./compiler/lua54.can:13 +local function newline() -- ./compiler/lua54.can:15 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 +if options["mapLines"] then -- ./compiler/lua54.can:17 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:17 -if source and line then -- ./compiler/lua54.can:19 -lastSource = source -- ./compiler/lua54.can:20 -lastLine = tonumber(line) -- ./compiler/lua54.can:21 -else -- ./compiler/lua54.can:21 +") -- ./compiler/lua54.can:19 +if source and line then -- ./compiler/lua54.can:21 +lastSource = source -- ./compiler/lua54.can:22 +lastLine = tonumber(line) -- ./compiler/lua54.can:23 +else -- ./compiler/lua54.can:23 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:23 -lastLine = lastLine + (1) -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -prevLinePos = lastInputPos -- ./compiler/lua54.can:28 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 -end -- ./compiler/lua54.can:30 -return r -- ./compiler/lua54.can:32 +") do -- ./compiler/lua54.can:25 +lastLine = lastLine + (1) -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +prevLinePos = lastInputPos -- ./compiler/lua54.can:30 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 end -- ./compiler/lua54.can:32 -local function indent() -- ./compiler/lua54.can:35 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 -return newline() -- ./compiler/lua54.can:37 -end -- ./compiler/lua54.can:37 -local function unindent() -- ./compiler/lua54.can:40 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 -return newline() -- ./compiler/lua54.can:42 -end -- ./compiler/lua54.can:42 -local states = { -- ./compiler/lua54.can:47 -["push"] = {}, -- ./compiler/lua54.can:48 -["destructuring"] = {}, -- ./compiler/lua54.can:49 -["scope"] = {} -- ./compiler/lua54.can:50 -} -- ./compiler/lua54.can:50 -local function push(name, state) -- ./compiler/lua54.can:53 -table["insert"](states[name], state) -- ./compiler/lua54.can:54 -return "" -- ./compiler/lua54.can:55 -end -- ./compiler/lua54.can:55 -local function pop(name) -- ./compiler/lua54.can:58 -table["remove"](states[name]) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function set(name, state) -- ./compiler/lua54.can:63 -states[name][# states[name]] = state -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function peek(name) -- ./compiler/lua54.can:68 -return states[name][# states[name]] -- ./compiler/lua54.can:69 -end -- ./compiler/lua54.can:69 -local function var(name) -- ./compiler/lua54.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 -end -- ./compiler/lua54.can:75 -local function tmp() -- ./compiler/lua54.can:79 -local scope = peek("scope") -- ./compiler/lua54.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 -table["insert"](scope, var) -- ./compiler/lua54.can:82 -return var -- ./compiler/lua54.can:83 -end -- ./compiler/lua54.can:83 -local required = {} -- ./compiler/lua54.can:87 -local requireStr = "" -- ./compiler/lua54.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 -if not required[req] then -- ./compiler/lua54.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 -required[req] = true -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -local loop = { -- ./compiler/lua54.can:99 -"While", -- ./compiler/lua54.can:99 -"Repeat", -- ./compiler/lua54.can:99 -"Fornum", -- ./compiler/lua54.can:99 -"Forin", -- ./compiler/lua54.can:99 -"WhileExpr", -- ./compiler/lua54.can:99 -"RepeatExpr", -- ./compiler/lua54.can:99 -"FornumExpr", -- ./compiler/lua54.can:99 -"ForinExpr" -- ./compiler/lua54.can:99 -} -- ./compiler/lua54.can:99 -local func = { -- ./compiler/lua54.can:100 -"Function", -- ./compiler/lua54.can:100 -"TableCompr", -- ./compiler/lua54.can:100 -"DoExpr", -- ./compiler/lua54.can:100 -"WhileExpr", -- ./compiler/lua54.can:100 -"RepeatExpr", -- ./compiler/lua54.can:100 -"IfExpr", -- ./compiler/lua54.can:100 -"FornumExpr", -- ./compiler/lua54.can:100 -"ForinExpr" -- ./compiler/lua54.can:100 -} -- ./compiler/lua54.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 -local tagsCheck = {} -- ./compiler/lua54.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 -tagsCheck[tag] = true -- ./compiler/lua54.can:107 -end -- ./compiler/lua54.can:107 -local nofollowCheck = {} -- ./compiler/lua54.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 -nofollowCheck[tag] = true -- ./compiler/lua54.can:111 -end -- ./compiler/lua54.can:111 -for _, node in ipairs(list) do -- ./compiler/lua54.can:113 -if type(node) == "table" then -- ./compiler/lua54.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 -return node -- ./compiler/lua54.can:116 -end -- ./compiler/lua54.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 -if r then -- ./compiler/lua54.can:120 -return r -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -return nil -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 -local tagsCheck = {} -- ./compiler/lua54.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 -tagsCheck[tag] = true -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local nofollowCheck = {} -- ./compiler/lua54.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 -nofollowCheck[tag] = true -- ./compiler/lua54.can:136 -end -- ./compiler/lua54.can:136 -local found = {} -- ./compiler/lua54.can:138 -for _, node in ipairs(list) do -- ./compiler/lua54.can:139 -if type(node) == "table" then -- ./compiler/lua54.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 -table["insert"](found, n) -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 -table["insert"](found, node) -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -return found -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -local function all(list, tags) -- ./compiler/lua54.can:155 -for _, node in ipairs(list) do -- ./compiler/lua54.can:156 -local ok = false -- ./compiler/lua54.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 -if node["tag"] == tag then -- ./compiler/lua54.can:159 -ok = true -- ./compiler/lua54.can:160 -break -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -if not ok then -- ./compiler/lua54.can:164 -return false -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -return true -- ./compiler/lua54.can:168 -end -- ./compiler/lua54.can:168 -local tags -- ./compiler/lua54.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 -end -- ./compiler/lua54.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 -end -- ./compiler/lua54.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local CONTINUE_START = function() -- ./compiler/lua54.can:188 -return "do" .. indent() -- ./compiler/lua54.can:189 +return r -- ./compiler/lua54.can:34 +end -- ./compiler/lua54.can:34 +local function indent() -- ./compiler/lua54.can:37 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 +return newline() -- ./compiler/lua54.can:39 +end -- ./compiler/lua54.can:39 +local function unindent() -- ./compiler/lua54.can:42 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 +return newline() -- ./compiler/lua54.can:44 +end -- ./compiler/lua54.can:44 +local states = { -- ./compiler/lua54.can:49 +["push"] = {}, -- ./compiler/lua54.can:50 +["destructuring"] = {}, -- ./compiler/lua54.can:51 +["scope"] = {}, -- ./compiler/lua54.can:52 +["macroargs"] = {} -- ./compiler/lua54.can:53 +} -- ./compiler/lua54.can:53 +local function push(name, state) -- ./compiler/lua54.can:56 +table["insert"](states[name], state) -- ./compiler/lua54.can:57 +return "" -- ./compiler/lua54.can:58 +end -- ./compiler/lua54.can:58 +local function pop(name) -- ./compiler/lua54.can:61 +table["remove"](states[name]) -- ./compiler/lua54.can:62 +return "" -- ./compiler/lua54.can:63 +end -- ./compiler/lua54.can:63 +local function set(name, state) -- ./compiler/lua54.can:66 +states[name][# states[name]] = state -- ./compiler/lua54.can:67 +return "" -- ./compiler/lua54.can:68 +end -- ./compiler/lua54.can:68 +local function peek(name) -- ./compiler/lua54.can:71 +return states[name][# states[name]] -- ./compiler/lua54.can:72 +end -- ./compiler/lua54.can:72 +local function var(name) -- ./compiler/lua54.can:77 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 +end -- ./compiler/lua54.can:78 +local function tmp() -- ./compiler/lua54.can:82 +local scope = peek("scope") -- ./compiler/lua54.can:83 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 +table["insert"](scope, var) -- ./compiler/lua54.can:85 +return var -- ./compiler/lua54.can:86 +end -- ./compiler/lua54.can:86 +local nomacro = { -- ./compiler/lua54.can:90 +["variables"] = {}, -- ./compiler/lua54.can:90 +["functions"] = {} -- ./compiler/lua54.can:90 +} -- ./compiler/lua54.can:90 +local required = {} -- ./compiler/lua54.can:93 +local requireStr = "" -- ./compiler/lua54.can:94 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 +if not required[req] then -- ./compiler/lua54.can:98 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 +required[req] = true -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +local loop = { -- ./compiler/lua54.can:105 +"While", -- ./compiler/lua54.can:105 +"Repeat", -- ./compiler/lua54.can:105 +"Fornum", -- ./compiler/lua54.can:105 +"Forin", -- ./compiler/lua54.can:105 +"WhileExpr", -- ./compiler/lua54.can:105 +"RepeatExpr", -- ./compiler/lua54.can:105 +"FornumExpr", -- ./compiler/lua54.can:105 +"ForinExpr" -- ./compiler/lua54.can:105 +} -- ./compiler/lua54.can:105 +local func = { -- ./compiler/lua54.can:106 +"Function", -- ./compiler/lua54.can:106 +"TableCompr", -- ./compiler/lua54.can:106 +"DoExpr", -- ./compiler/lua54.can:106 +"WhileExpr", -- ./compiler/lua54.can:106 +"RepeatExpr", -- ./compiler/lua54.can:106 +"IfExpr", -- ./compiler/lua54.can:106 +"FornumExpr", -- ./compiler/lua54.can:106 +"ForinExpr" -- ./compiler/lua54.can:106 +} -- ./compiler/lua54.can:106 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 +local tagsCheck = {} -- ./compiler/lua54.can:111 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 +tagsCheck[tag] = true -- ./compiler/lua54.can:113 +end -- ./compiler/lua54.can:113 +local nofollowCheck = {} -- ./compiler/lua54.can:115 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 +nofollowCheck[tag] = true -- ./compiler/lua54.can:117 +end -- ./compiler/lua54.can:117 +for _, node in ipairs(list) do -- ./compiler/lua54.can:119 +if type(node) == "table" then -- ./compiler/lua54.can:120 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 +return node -- ./compiler/lua54.can:122 +end -- ./compiler/lua54.can:122 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 +if r then -- ./compiler/lua54.can:126 +return r -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +return nil -- ./compiler/lua54.can:130 +end -- ./compiler/lua54.can:130 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 +local tagsCheck = {} -- ./compiler/lua54.can:136 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 +tagsCheck[tag] = true -- ./compiler/lua54.can:138 +end -- ./compiler/lua54.can:138 +local nofollowCheck = {} -- ./compiler/lua54.can:140 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 +nofollowCheck[tag] = true -- ./compiler/lua54.can:142 +end -- ./compiler/lua54.can:142 +local found = {} -- ./compiler/lua54.can:144 +for _, node in ipairs(list) do -- ./compiler/lua54.can:145 +if type(node) == "table" then -- ./compiler/lua54.can:146 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 +table["insert"](found, n) -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 +table["insert"](found, node) -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +return found -- ./compiler/lua54.can:157 +end -- ./compiler/lua54.can:157 +local function all(list, tags) -- ./compiler/lua54.can:161 +for _, node in ipairs(list) do -- ./compiler/lua54.can:162 +local ok = false -- ./compiler/lua54.can:163 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 +if node["tag"] == tag then -- ./compiler/lua54.can:165 +ok = true -- ./compiler/lua54.can:166 +break -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +if not ok then -- ./compiler/lua54.can:170 +return false -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +return true -- ./compiler/lua54.can:174 +end -- ./compiler/lua54.can:174 +local tags -- ./compiler/lua54.can:178 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 +end -- ./compiler/lua54.can:182 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +end -- ./compiler/lua54.can:184 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 end -- ./compiler/lua54.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 end -- ./compiler/lua54.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 -local vars = {} -- ./compiler/lua54.can:195 -local values = {} -- ./compiler/lua54.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 -for _, v in ipairs(list) do -- ./compiler/lua54.can:198 -local var, val -- ./compiler/lua54.can:199 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 -var = v -- ./compiler/lua54.can:201 -val = { -- ./compiler/lua54.can:202 -["tag"] = "Index", -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "Id", -- ./compiler/lua54.can:202 -list["id"] -- ./compiler/lua54.can:202 -}, -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "String", -- ./compiler/lua54.can:202 -v[1] -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 -var = v[2] -- ./compiler/lua54.can:204 -val = { -- ./compiler/lua54.can:205 -["tag"] = "Index", -- ./compiler/lua54.can:205 -{ -- ./compiler/lua54.can:205 -["tag"] = "Id", -- ./compiler/lua54.can:205 -list["id"] -- ./compiler/lua54.can:205 -}, -- ./compiler/lua54.can:205 -v[1] -- ./compiler/lua54.can:205 -} -- ./compiler/lua54.can:205 -else -- ./compiler/lua54.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 -end -- ./compiler/lua54.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["rightOp"], -- ./compiler/lua54.can:210 -var, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["leftOp"], -- ./compiler/lua54.can:210 -val, -- ./compiler/lua54.can:210 -var -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 -val = { -- ./compiler/lua54.can:212 -["tag"] = "Op", -- ./compiler/lua54.can:212 -destructured["rightOp"], -- ./compiler/lua54.can:212 -var, -- ./compiler/lua54.can:212 -val -- ./compiler/lua54.can:212 -} -- ./compiler/lua54.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 -val = { -- ./compiler/lua54.can:214 -["tag"] = "Op", -- ./compiler/lua54.can:214 -destructured["leftOp"], -- ./compiler/lua54.can:214 -val, -- ./compiler/lua54.can:214 -var -- ./compiler/lua54.can:214 -} -- ./compiler/lua54.can:214 -end -- ./compiler/lua54.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -if # vars > 0 then -- ./compiler/lua54.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 -if newlineAfter then -- ./compiler/lua54.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 -else -- ./compiler/lua54.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -else -- ./compiler/lua54.can:225 -return "" -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -tags = setmetatable({ -- ./compiler/lua54.can:233 -["Block"] = function(t) -- ./compiler/lua54.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 -hasPush = false -- ./compiler/lua54.can:239 -end -- ./compiler/lua54.can:239 -local r = push("scope", {}) -- ./compiler/lua54.can:241 -if hasPush then -- ./compiler/lua54.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 -end -- ./compiler/lua54.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 -end -- ./compiler/lua54.can:246 -if t[# t] then -- ./compiler/lua54.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +local CONTINUE_START = function() -- ./compiler/lua54.can:194 +return "do" .. indent() -- ./compiler/lua54.can:195 +end -- ./compiler/lua54.can:195 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 +end -- ./compiler/lua54.can:198 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 +local vars = {} -- ./compiler/lua54.can:201 +local values = {} -- ./compiler/lua54.can:202 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 +for _, v in ipairs(list) do -- ./compiler/lua54.can:204 +local var, val -- ./compiler/lua54.can:205 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 +var = v -- ./compiler/lua54.can:207 +val = { -- ./compiler/lua54.can:208 +["tag"] = "Index", -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "Id", -- ./compiler/lua54.can:208 +list["id"] -- ./compiler/lua54.can:208 +}, -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "String", -- ./compiler/lua54.can:208 +v[1] -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 +var = v[2] -- ./compiler/lua54.can:210 +val = { -- ./compiler/lua54.can:211 +["tag"] = "Index", -- ./compiler/lua54.can:211 +{ -- ./compiler/lua54.can:211 +["tag"] = "Id", -- ./compiler/lua54.can:211 +list["id"] -- ./compiler/lua54.can:211 +}, -- ./compiler/lua54.can:211 +v[1] -- ./compiler/lua54.can:211 +} -- ./compiler/lua54.can:211 +else -- ./compiler/lua54.can:211 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 +end -- ./compiler/lua54.can:213 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 +val = { -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["rightOp"], -- ./compiler/lua54.can:216 +var, -- ./compiler/lua54.can:216 +{ -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["leftOp"], -- ./compiler/lua54.can:216 +val, -- ./compiler/lua54.can:216 +var -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +val = { -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["rightOp"], -- ./compiler/lua54.can:218 +var, -- ./compiler/lua54.can:218 +val -- ./compiler/lua54.can:218 +} -- ./compiler/lua54.can:218 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +val = { -- ./compiler/lua54.can:220 +["tag"] = "Op", -- ./compiler/lua54.can:220 +destructured["leftOp"], -- ./compiler/lua54.can:220 +val, -- ./compiler/lua54.can:220 +var -- ./compiler/lua54.can:220 +} -- ./compiler/lua54.can:220 +end -- ./compiler/lua54.can:220 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +if # vars > 0 then -- ./compiler/lua54.can:226 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 +if newlineAfter then -- ./compiler/lua54.can:228 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 +else -- ./compiler/lua54.can:229 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 +end -- ./compiler/lua54.can:231 +else -- ./compiler/lua54.can:231 +return "" -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +tags = setmetatable({ -- ./compiler/lua54.can:239 +["Block"] = function(t) -- ./compiler/lua54.can:241 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 +hasPush = false -- ./compiler/lua54.can:245 +end -- ./compiler/lua54.can:245 +local r = push("scope", {}) -- ./compiler/lua54.can:247 +if hasPush then -- ./compiler/lua54.can:248 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 end -- ./compiler/lua54.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 end -- ./compiler/lua54.can:252 -return r .. pop("scope") -- ./compiler/lua54.can:254 -end, -- ./compiler/lua54.can:254 -["Do"] = function(t) -- ./compiler/lua54.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 -end, -- ./compiler/lua54.can:261 -["Set"] = function(t) -- ./compiler/lua54.can:264 -local expr = t[# t] -- ./compiler/lua54.can:266 -local vars, values = {}, {} -- ./compiler/lua54.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 -else -- ./compiler/lua54.can:272 -table["insert"](vars, n) -- ./compiler/lua54.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 -local r = "" -- ./compiler/lua54.can:280 -if # vars > 0 then -- ./compiler/lua54.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 -end -- ./compiler/lua54.can:282 -if # destructuringVars > 0 then -- ./compiler/lua54.can:284 -local destructured = {} -- ./compiler/lua54.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 -end -- ./compiler/lua54.can:287 -return r -- ./compiler/lua54.can:289 -elseif # t == 4 then -- ./compiler/lua54.can:290 -if t[3] == "=" then -- ./compiler/lua54.can:291 -local r = "" -- ./compiler/lua54.can:292 -if # vars > 0 then -- ./compiler/lua54.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 -t[2], -- ./compiler/lua54.can:294 -vars[1], -- ./compiler/lua54.can:294 -{ -- ./compiler/lua54.can:294 -["tag"] = "Paren", -- ./compiler/lua54.can:294 -values[1] -- ./compiler/lua54.can:294 -} -- ./compiler/lua54.can:294 -}, "Op")) -- ./compiler/lua54.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 -t[2], -- ./compiler/lua54.can:296 -vars[i], -- ./compiler/lua54.can:296 -{ -- ./compiler/lua54.can:296 -["tag"] = "Paren", -- ./compiler/lua54.can:296 -values[i] -- ./compiler/lua54.can:296 -} -- ./compiler/lua54.can:296 -}, "Op")) -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -if # destructuringVars > 0 then -- ./compiler/lua54.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +if t[# t] then -- ./compiler/lua54.can:254 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 +end -- ./compiler/lua54.can:255 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 +end -- ./compiler/lua54.can:258 +return r .. pop("scope") -- ./compiler/lua54.can:260 +end, -- ./compiler/lua54.can:260 +["Do"] = function(t) -- ./compiler/lua54.can:266 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 +end, -- ./compiler/lua54.can:267 +["Set"] = function(t) -- ./compiler/lua54.can:270 +local expr = t[# t] -- ./compiler/lua54.can:272 +local vars, values = {}, {} -- ./compiler/lua54.can:273 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 +else -- ./compiler/lua54.can:278 +table["insert"](vars, n) -- ./compiler/lua54.can:280 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 +local r = "" -- ./compiler/lua54.can:286 +if # vars > 0 then -- ./compiler/lua54.can:287 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 +end -- ./compiler/lua54.can:288 +if # destructuringVars > 0 then -- ./compiler/lua54.can:290 +local destructured = {} -- ./compiler/lua54.can:291 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 +end -- ./compiler/lua54.can:293 +return r -- ./compiler/lua54.can:295 +elseif # t == 4 then -- ./compiler/lua54.can:296 +if t[3] == "=" then -- ./compiler/lua54.can:297 +local r = "" -- ./compiler/lua54.can:298 +if # vars > 0 then -- ./compiler/lua54.can:299 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 +t[2], -- ./compiler/lua54.can:300 +vars[1], -- ./compiler/lua54.can:300 +{ -- ./compiler/lua54.can:300 +["tag"] = "Paren", -- ./compiler/lua54.can:300 +values[1] -- ./compiler/lua54.can:300 +} -- ./compiler/lua54.can:300 +}, "Op")) -- ./compiler/lua54.can:300 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +t[2], -- ./compiler/lua54.can:302 +vars[i], -- ./compiler/lua54.can:302 +{ -- ./compiler/lua54.can:302 +["tag"] = "Paren", -- ./compiler/lua54.can:302 +values[i] -- ./compiler/lua54.can:302 +} -- ./compiler/lua54.can:302 +}, "Op")) -- ./compiler/lua54.can:302 end -- ./compiler/lua54.can:302 -return r -- ./compiler/lua54.can:304 -else -- ./compiler/lua54.can:304 -local r = "" -- ./compiler/lua54.can:306 -if # vars > 0 then -- ./compiler/lua54.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 -t[3], -- ./compiler/lua54.can:308 -{ -- ./compiler/lua54.can:308 -["tag"] = "Paren", -- ./compiler/lua54.can:308 -values[1] -- ./compiler/lua54.can:308 -}, -- ./compiler/lua54.can:308 -vars[1] -- ./compiler/lua54.can:308 -}, "Op")) -- ./compiler/lua54.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 -t[3], -- ./compiler/lua54.can:310 -{ -- ./compiler/lua54.can:310 -["tag"] = "Paren", -- ./compiler/lua54.can:310 -values[i] -- ./compiler/lua54.can:310 -}, -- ./compiler/lua54.can:310 -vars[i] -- ./compiler/lua54.can:310 -}, "Op")) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -if # destructuringVars > 0 then -- ./compiler/lua54.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:302 +if # destructuringVars > 0 then -- ./compiler/lua54.can:305 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 +end -- ./compiler/lua54.can:308 +return r -- ./compiler/lua54.can:310 +else -- ./compiler/lua54.can:310 +local r = "" -- ./compiler/lua54.can:312 +if # vars > 0 then -- ./compiler/lua54.can:313 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 +t[3], -- ./compiler/lua54.can:314 +{ -- ./compiler/lua54.can:314 +["tag"] = "Paren", -- ./compiler/lua54.can:314 +values[1] -- ./compiler/lua54.can:314 +}, -- ./compiler/lua54.can:314 +vars[1] -- ./compiler/lua54.can:314 +}, "Op")) -- ./compiler/lua54.can:314 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +t[3], -- ./compiler/lua54.can:316 +{ -- ./compiler/lua54.can:316 +["tag"] = "Paren", -- ./compiler/lua54.can:316 +values[i] -- ./compiler/lua54.can:316 +}, -- ./compiler/lua54.can:316 +vars[i] -- ./compiler/lua54.can:316 +}, "Op")) -- ./compiler/lua54.can:316 end -- ./compiler/lua54.can:316 -return r -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -else -- ./compiler/lua54.can:318 -local r = "" -- ./compiler/lua54.can:321 -if # vars > 0 then -- ./compiler/lua54.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 -t[2], -- ./compiler/lua54.can:323 -vars[1], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Op", -- ./compiler/lua54.can:323 -t[4], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Paren", -- ./compiler/lua54.can:323 -values[1] -- ./compiler/lua54.can:323 -}, -- ./compiler/lua54.can:323 -vars[1] -- ./compiler/lua54.can:323 -} -- ./compiler/lua54.can:323 -}, "Op")) -- ./compiler/lua54.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 -t[2], -- ./compiler/lua54.can:325 -vars[i], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Op", -- ./compiler/lua54.can:325 -t[4], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Paren", -- ./compiler/lua54.can:325 -values[i] -- ./compiler/lua54.can:325 -}, -- ./compiler/lua54.can:325 -vars[i] -- ./compiler/lua54.can:325 -} -- ./compiler/lua54.can:325 -}, "Op")) -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -if # destructuringVars > 0 then -- ./compiler/lua54.can:328 -local destructured = { -- ./compiler/lua54.can:329 -["rightOp"] = t[2], -- ./compiler/lua54.can:329 -["leftOp"] = t[4] -- ./compiler/lua54.can:329 +end -- ./compiler/lua54.can:316 +if # destructuringVars > 0 then -- ./compiler/lua54.can:319 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 +end -- ./compiler/lua54.can:322 +return r -- ./compiler/lua54.can:324 +end -- ./compiler/lua54.can:324 +else -- ./compiler/lua54.can:324 +local r = "" -- ./compiler/lua54.can:327 +if # vars > 0 then -- ./compiler/lua54.can:328 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 +t[2], -- ./compiler/lua54.can:329 +vars[1], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Op", -- ./compiler/lua54.can:329 +t[4], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Paren", -- ./compiler/lua54.can:329 +values[1] -- ./compiler/lua54.can:329 +}, -- ./compiler/lua54.can:329 +vars[1] -- ./compiler/lua54.can:329 } -- ./compiler/lua54.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:329 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +t[2], -- ./compiler/lua54.can:331 +vars[i], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Op", -- ./compiler/lua54.can:331 +t[4], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Paren", -- ./compiler/lua54.can:331 +values[i] -- ./compiler/lua54.can:331 +}, -- ./compiler/lua54.can:331 +vars[i] -- ./compiler/lua54.can:331 +} -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:331 end -- ./compiler/lua54.can:331 -return r -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end, -- ./compiler/lua54.can:333 -["While"] = function(t) -- ./compiler/lua54.can:337 -local r = "" -- ./compiler/lua54.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 -if # lets > 0 then -- ./compiler/lua54.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 -if # lets > 0 then -- ./compiler/lua54.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 -end -- ./compiler/lua54.can:349 -if hasContinue then -- ./compiler/lua54.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 -if hasContinue then -- ./compiler/lua54.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 -end -- ./compiler/lua54.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 -if # lets > 0 then -- ./compiler/lua54.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 -end -- ./compiler/lua54.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 -end -- ./compiler/lua54.can:363 -return r -- ./compiler/lua54.can:365 -end, -- ./compiler/lua54.can:365 -["Repeat"] = function(t) -- ./compiler/lua54.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 -local r = "repeat" .. indent() -- ./compiler/lua54.can:370 -if hasContinue then -- ./compiler/lua54.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 -end -- ./compiler/lua54.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 -if hasContinue then -- ./compiler/lua54.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 -end -- ./compiler/lua54.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 -return r -- ./compiler/lua54.can:379 -end, -- ./compiler/lua54.can:379 -["If"] = function(t) -- ./compiler/lua54.can:382 -local r = "" -- ./compiler/lua54.can:383 -local toClose = 0 -- ./compiler/lua54.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 -if # lets > 0 then -- ./compiler/lua54.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 -toClose = toClose + (1) -- ./compiler/lua54.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 -if # lets > 0 then -- ./compiler/lua54.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 -toClose = toClose + (1) -- ./compiler/lua54.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 -end -- ./compiler/lua54.can:400 -else -- ./compiler/lua54.can:400 -r = r .. ("else") -- ./compiler/lua54.can:403 -end -- ./compiler/lua54.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 -end -- ./compiler/lua54.can:405 -if # t % 2 == 1 then -- ./compiler/lua54.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -r = r .. ("end") -- ./compiler/lua54.can:410 -for i = 1, toClose do -- ./compiler/lua54.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 -end -- ./compiler/lua54.can:412 -return r -- ./compiler/lua54.can:414 -end, -- ./compiler/lua54.can:414 -["Fornum"] = function(t) -- ./compiler/lua54.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 -if # t == 5 then -- ./compiler/lua54.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 -if hasContinue then -- ./compiler/lua54.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 -end -- ./compiler/lua54.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 -if hasContinue then -- ./compiler/lua54.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 -end -- ./compiler/lua54.can:427 -return r .. unindent() .. "end" -- ./compiler/lua54.can:429 -else -- ./compiler/lua54.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 -if hasContinue then -- ./compiler/lua54.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 -end -- ./compiler/lua54.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 -if hasContinue then -- ./compiler/lua54.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 -end -- ./compiler/lua54.can:438 -return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:331 +if # destructuringVars > 0 then -- ./compiler/lua54.can:334 +local destructured = { -- ./compiler/lua54.can:335 +["rightOp"] = t[2], -- ./compiler/lua54.can:335 +["leftOp"] = t[4] -- ./compiler/lua54.can:335 +} -- ./compiler/lua54.can:335 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 +end -- ./compiler/lua54.can:337 +return r -- ./compiler/lua54.can:339 +end -- ./compiler/lua54.can:339 +end, -- ./compiler/lua54.can:339 +["While"] = function(t) -- ./compiler/lua54.can:343 +local r = "" -- ./compiler/lua54.can:344 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 +if # lets > 0 then -- ./compiler/lua54.can:347 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 +if # lets > 0 then -- ./compiler/lua54.can:354 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 +end -- ./compiler/lua54.can:355 +if hasContinue then -- ./compiler/lua54.can:357 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 +end -- ./compiler/lua54.can:358 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 +if hasContinue then -- ./compiler/lua54.can:361 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 +end -- ./compiler/lua54.can:362 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 +if # lets > 0 then -- ./compiler/lua54.can:365 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 +end -- ./compiler/lua54.can:367 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +end -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:371 +end, -- ./compiler/lua54.can:371 +["Repeat"] = function(t) -- ./compiler/lua54.can:374 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 +local r = "repeat" .. indent() -- ./compiler/lua54.can:376 +if hasContinue then -- ./compiler/lua54.can:377 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 +end -- ./compiler/lua54.can:378 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 +if hasContinue then -- ./compiler/lua54.can:381 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 +end -- ./compiler/lua54.can:382 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 +return r -- ./compiler/lua54.can:385 +end, -- ./compiler/lua54.can:385 +["If"] = function(t) -- ./compiler/lua54.can:388 +local r = "" -- ./compiler/lua54.can:389 +local toClose = 0 -- ./compiler/lua54.can:390 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 +if # lets > 0 then -- ./compiler/lua54.can:392 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 +toClose = toClose + (1) -- ./compiler/lua54.can:394 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 +if # lets > 0 then -- ./compiler/lua54.can:402 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 +toClose = toClose + (1) -- ./compiler/lua54.can:404 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 +end -- ./compiler/lua54.can:406 +else -- ./compiler/lua54.can:406 +r = r .. ("else") -- ./compiler/lua54.can:409 +end -- ./compiler/lua54.can:409 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +end -- ./compiler/lua54.can:411 +if # t % 2 == 1 then -- ./compiler/lua54.can:413 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 +end -- ./compiler/lua54.can:414 +r = r .. ("end") -- ./compiler/lua54.can:416 +for i = 1, toClose do -- ./compiler/lua54.can:417 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 +end -- ./compiler/lua54.can:418 +return r -- ./compiler/lua54.can:420 +end, -- ./compiler/lua54.can:420 +["Fornum"] = function(t) -- ./compiler/lua54.can:423 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 +if # t == 5 then -- ./compiler/lua54.can:425 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 +if hasContinue then -- ./compiler/lua54.can:428 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 +end -- ./compiler/lua54.can:429 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 +if hasContinue then -- ./compiler/lua54.can:432 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 +end -- ./compiler/lua54.can:433 +return r .. unindent() .. "end" -- ./compiler/lua54.can:435 +else -- ./compiler/lua54.can:435 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 +if hasContinue then -- ./compiler/lua54.can:439 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 end -- ./compiler/lua54.can:440 -end, -- ./compiler/lua54.can:440 -["Forin"] = function(t) -- ./compiler/lua54.can:444 -local destructured = {} -- ./compiler/lua54.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 -if hasContinue then -- ./compiler/lua54.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 -end -- ./compiler/lua54.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 -if hasContinue then -- ./compiler/lua54.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 -end -- ./compiler/lua54.can:453 -return r .. unindent() .. "end" -- ./compiler/lua54.can:455 -end, -- ./compiler/lua54.can:455 -["Local"] = function(t) -- ./compiler/lua54.can:458 -local destructured = {} -- ./compiler/lua54.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 -if t[2][1] then -- ./compiler/lua54.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 -end -- ./compiler/lua54.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 -end, -- ./compiler/lua54.can:464 -["Let"] = function(t) -- ./compiler/lua54.can:467 -local destructured = {} -- ./compiler/lua54.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 -local r = "local " .. nameList -- ./compiler/lua54.can:470 -if t[2][1] then -- ./compiler/lua54.can:471 -if all(t[2], { -- ./compiler/lua54.can:472 -"Nil", -- ./compiler/lua54.can:472 -"Dots", -- ./compiler/lua54.can:472 -"Boolean", -- ./compiler/lua54.can:472 -"Number", -- ./compiler/lua54.can:472 -"String" -- ./compiler/lua54.can:472 -}) then -- ./compiler/lua54.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 -else -- ./compiler/lua54.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 -end, -- ./compiler/lua54.can:478 -["Localrec"] = function(t) -- ./compiler/lua54.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 -end, -- ./compiler/lua54.can:482 -["Goto"] = function(t) -- ./compiler/lua54.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Label"] = function(t) -- ./compiler/lua54.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Return"] = function(t) -- ./compiler/lua54.can:493 -local push = peek("push") -- ./compiler/lua54.can:494 -if push then -- ./compiler/lua54.can:495 -local r = "" -- ./compiler/lua54.can:496 -for _, val in ipairs(t) do -- ./compiler/lua54.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 -end -- ./compiler/lua54.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 -else -- ./compiler/lua54.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 -end -- ./compiler/lua54.can:502 -end, -- ./compiler/lua54.can:502 -["Push"] = function(t) -- ./compiler/lua54.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 -r = "" -- ./compiler/lua54.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -if t[# t] then -- ./compiler/lua54.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 -else -- ./compiler/lua54.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 +if hasContinue then -- ./compiler/lua54.can:443 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 +end -- ./compiler/lua54.can:444 +return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +end -- ./compiler/lua54.can:446 +end, -- ./compiler/lua54.can:446 +["Forin"] = function(t) -- ./compiler/lua54.can:450 +local destructured = {} -- ./compiler/lua54.can:451 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 +if hasContinue then -- ./compiler/lua54.can:454 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 +end -- ./compiler/lua54.can:455 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 +if hasContinue then -- ./compiler/lua54.can:458 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 +end -- ./compiler/lua54.can:459 +return r .. unindent() .. "end" -- ./compiler/lua54.can:461 +end, -- ./compiler/lua54.can:461 +["Local"] = function(t) -- ./compiler/lua54.can:464 +local destructured = {} -- ./compiler/lua54.can:465 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 +if t[2][1] then -- ./compiler/lua54.can:467 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 +end -- ./compiler/lua54.can:468 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 +end, -- ./compiler/lua54.can:470 +["Let"] = function(t) -- ./compiler/lua54.can:473 +local destructured = {} -- ./compiler/lua54.can:474 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 +local r = "local " .. nameList -- ./compiler/lua54.can:476 +if t[2][1] then -- ./compiler/lua54.can:477 +if all(t[2], { -- ./compiler/lua54.can:478 +"Nil", -- ./compiler/lua54.can:478 +"Dots", -- ./compiler/lua54.can:478 +"Boolean", -- ./compiler/lua54.can:478 +"Number", -- ./compiler/lua54.can:478 +"String" -- ./compiler/lua54.can:478 +}) then -- ./compiler/lua54.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 +else -- ./compiler/lua54.can:479 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 +end, -- ./compiler/lua54.can:484 +["Localrec"] = function(t) -- ./compiler/lua54.can:487 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 +end, -- ./compiler/lua54.can:488 +["Goto"] = function(t) -- ./compiler/lua54.can:491 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 +end, -- ./compiler/lua54.can:492 +["Label"] = function(t) -- ./compiler/lua54.can:495 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 +end, -- ./compiler/lua54.can:496 +["Return"] = function(t) -- ./compiler/lua54.can:499 +local push = peek("push") -- ./compiler/lua54.can:500 +if push then -- ./compiler/lua54.can:501 +local r = "" -- ./compiler/lua54.can:502 +for _, val in ipairs(t) do -- ./compiler/lua54.can:503 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 +end -- ./compiler/lua54.can:504 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 +else -- ./compiler/lua54.can:506 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 +end -- ./compiler/lua54.can:508 +end, -- ./compiler/lua54.can:508 +["Push"] = function(t) -- ./compiler/lua54.can:512 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 +r = "" -- ./compiler/lua54.can:514 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 end -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -return r -- ./compiler/lua54.can:519 -end, -- ./compiler/lua54.can:519 -["Break"] = function() -- ./compiler/lua54.can:522 -return "break" -- ./compiler/lua54.can:523 -end, -- ./compiler/lua54.can:523 -["Continue"] = function() -- ./compiler/lua54.can:526 -return "goto " .. var("continue") -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Nil"] = function() -- ./compiler/lua54.can:534 -return "nil" -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Dots"] = function() -- ./compiler/lua54.can:538 -return "..." -- ./compiler/lua54.can:539 -end, -- ./compiler/lua54.can:539 -["Boolean"] = function(t) -- ./compiler/lua54.can:542 -return tostring(t[1]) -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Number"] = function(t) -- ./compiler/lua54.can:546 -return tostring(t[1]) -- ./compiler/lua54.can:547 -end, -- ./compiler/lua54.can:547 -["String"] = function(t) -- ./compiler/lua54.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 -end, -- ./compiler/lua54.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 -local r = "(" -- ./compiler/lua54.can:555 -local decl = {} -- ./compiler/lua54.can:556 -if t[1][1] then -- ./compiler/lua54.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 -r = r .. (id) -- ./compiler/lua54.can:563 -else -- ./compiler/lua54.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 -end -- ./compiler/lua54.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 -r = r .. (", " .. id) -- ./compiler/lua54.can:573 -else -- ./compiler/lua54.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 -r = r .. (d .. newline()) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 -end -- ./compiler/lua54.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 -if hasPush then -- ./compiler/lua54.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 -else -- ./compiler/lua54.can:588 -push("push", false) -- ./compiler/lua54.can:590 -end -- ./compiler/lua54.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 -end -- ./compiler/lua54.can:594 -pop("push") -- ./compiler/lua54.can:596 -return r .. unindent() .. "end" -- ./compiler/lua54.can:597 -end, -- ./compiler/lua54.can:597 -["Function"] = function(t) -- ./compiler/lua54.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 -end, -- ./compiler/lua54.can:600 -["Pair"] = function(t) -- ./compiler/lua54.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 -end, -- ./compiler/lua54.can:604 -["Table"] = function(t) -- ./compiler/lua54.can:606 -if # t == 0 then -- ./compiler/lua54.can:607 -return "{}" -- ./compiler/lua54.can:608 -elseif # t == 1 then -- ./compiler/lua54.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 -else -- ./compiler/lua54.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 -end -- ./compiler/lua54.can:612 -end, -- ./compiler/lua54.can:612 -["TableCompr"] = function(t) -- ./compiler/lua54.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 -end, -- ./compiler/lua54.can:617 -["Op"] = function(t) -- ./compiler/lua54.can:620 -local r -- ./compiler/lua54.can:621 -if # t == 2 then -- ./compiler/lua54.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +if t[# t] then -- ./compiler/lua54.can:518 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 +else -- ./compiler/lua54.can:520 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +return r -- ./compiler/lua54.can:525 +end, -- ./compiler/lua54.can:525 +["Break"] = function() -- ./compiler/lua54.can:528 +return "break" -- ./compiler/lua54.can:529 +end, -- ./compiler/lua54.can:529 +["Continue"] = function() -- ./compiler/lua54.can:532 +return "goto " .. var("continue") -- ./compiler/lua54.can:533 +end, -- ./compiler/lua54.can:533 +["Nil"] = function() -- ./compiler/lua54.can:540 +return "nil" -- ./compiler/lua54.can:541 +end, -- ./compiler/lua54.can:541 +["Dots"] = function() -- ./compiler/lua54.can:544 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 +return r -- ./compiler/lua54.can:550 +else -- ./compiler/lua54.can:550 +return "..." -- ./compiler/lua54.can:552 +end -- ./compiler/lua54.can:552 +end, -- ./compiler/lua54.can:552 +["Boolean"] = function(t) -- ./compiler/lua54.can:556 +return tostring(t[1]) -- ./compiler/lua54.can:557 +end, -- ./compiler/lua54.can:557 +["Number"] = function(t) -- ./compiler/lua54.can:560 +return tostring(t[1]) -- ./compiler/lua54.can:561 +end, -- ./compiler/lua54.can:561 +["String"] = function(t) -- ./compiler/lua54.can:564 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 +end, -- ./compiler/lua54.can:565 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 +local r = "(" -- ./compiler/lua54.can:569 +local decl = {} -- ./compiler/lua54.can:570 +if t[1][1] then -- ./compiler/lua54.can:571 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 +r = r .. (id) -- ./compiler/lua54.can:577 +else -- ./compiler/lua54.can:577 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 +end -- ./compiler/lua54.can:579 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 +r = r .. (", " .. id) -- ./compiler/lua54.can:587 +else -- ./compiler/lua54.can:587 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 +r = r .. (d .. newline()) -- ./compiler/lua54.can:595 +end -- ./compiler/lua54.can:595 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 +end -- ./compiler/lua54.can:598 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 +if hasPush then -- ./compiler/lua54.can:601 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 +else -- ./compiler/lua54.can:602 +push("push", false) -- ./compiler/lua54.can:604 +end -- ./compiler/lua54.can:604 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 +end -- ./compiler/lua54.can:608 +pop("push") -- ./compiler/lua54.can:610 +return r .. unindent() .. "end" -- ./compiler/lua54.can:611 +end, -- ./compiler/lua54.can:611 +["Function"] = function(t) -- ./compiler/lua54.can:613 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 +end, -- ./compiler/lua54.can:614 +["Pair"] = function(t) -- ./compiler/lua54.can:617 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 +end, -- ./compiler/lua54.can:618 +["Table"] = function(t) -- ./compiler/lua54.can:620 +if # t == 0 then -- ./compiler/lua54.can:621 +return "{}" -- ./compiler/lua54.can:622 +elseif # t == 1 then -- ./compiler/lua54.can:623 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 else -- ./compiler/lua54.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 end -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 -else -- ./compiler/lua54.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -return r -- ./compiler/lua54.can:635 -end, -- ./compiler/lua54.can:635 -["Paren"] = function(t) -- ./compiler/lua54.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 -end, -- ./compiler/lua54.can:639 -["MethodStub"] = function(t) -- ./compiler/lua54.can:642 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 -end, -- ./compiler/lua54.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 -end, -- ./compiler/lua54.can:658 -["LetExpr"] = function(t) -- ./compiler/lua54.can:665 -return lua(t[1][1]) -- ./compiler/lua54.can:666 -end, -- ./compiler/lua54.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 -local r = "(function()" .. indent() -- ./compiler/lua54.can:672 -if hasPush then -- ./compiler/lua54.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 -else -- ./compiler/lua54.can:674 -push("push", false) -- ./compiler/lua54.can:676 -end -- ./compiler/lua54.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 -if hasPush then -- ./compiler/lua54.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 -end -- ./compiler/lua54.can:680 -pop("push") -- ./compiler/lua54.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 -return r -- ./compiler/lua54.can:684 -end, -- ./compiler/lua54.can:684 -["DoExpr"] = function(t) -- ./compiler/lua54.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 -end -- ./compiler/lua54.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 -end, -- ./compiler/lua54.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 -end, -- ./compiler/lua54.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 -end, -- ./compiler/lua54.can:699 -["IfExpr"] = function(t) -- ./compiler/lua54.can:702 -for i = 2, # t do -- ./compiler/lua54.can:703 -local block = t[i] -- ./compiler/lua54.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:626 +["TableCompr"] = function(t) -- ./compiler/lua54.can:630 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 +end, -- ./compiler/lua54.can:631 +["Op"] = function(t) -- ./compiler/lua54.can:634 +local r -- ./compiler/lua54.can:635 +if # t == 2 then -- ./compiler/lua54.can:636 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 +else -- ./compiler/lua54.can:638 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 +end -- ./compiler/lua54.can:640 +else -- ./compiler/lua54.can:640 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 +else -- ./compiler/lua54.can:644 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +return r -- ./compiler/lua54.can:649 +end, -- ./compiler/lua54.can:649 +["Paren"] = function(t) -- ./compiler/lua54.can:652 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 +end, -- ./compiler/lua54.can:653 +["MethodStub"] = function(t) -- ./compiler/lua54.can:656 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 +end, -- ./compiler/lua54.can:662 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 +end, -- ./compiler/lua54.can:672 +["LetExpr"] = function(t) -- ./compiler/lua54.can:679 +return lua(t[1][1]) -- ./compiler/lua54.can:680 +end, -- ./compiler/lua54.can:680 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 +local r = "(function()" .. indent() -- ./compiler/lua54.can:686 +if hasPush then -- ./compiler/lua54.can:687 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 +else -- ./compiler/lua54.can:688 +push("push", false) -- ./compiler/lua54.can:690 +end -- ./compiler/lua54.can:690 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 +if hasPush then -- ./compiler/lua54.can:693 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 +end -- ./compiler/lua54.can:694 +pop("push") -- ./compiler/lua54.can:696 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 +return r -- ./compiler/lua54.can:698 +end, -- ./compiler/lua54.can:698 +["DoExpr"] = function(t) -- ./compiler/lua54.can:701 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 +end -- ./compiler/lua54.can:703 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 +end, -- ./compiler/lua54.can:705 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 end, -- ./compiler/lua54.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 end, -- ./compiler/lua54.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 -end, -- ./compiler/lua54.can:717 -["Call"] = function(t) -- ./compiler/lua54.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 -else -- ./compiler/lua54.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 -end -- ./compiler/lua54.can:730 -else -- ./compiler/lua54.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 -end -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["SafeCall"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 -else -- ./compiler/lua54.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 -end -- ./compiler/lua54.can:741 -end, -- ./compiler/lua54.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 -if start == nil then start = 1 end -- ./compiler/lua54.can:746 -local r -- ./compiler/lua54.can:747 -if t[start] then -- ./compiler/lua54.can:748 -r = lua(t[start]) -- ./compiler/lua54.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 -end -- ./compiler/lua54.can:751 +["IfExpr"] = function(t) -- ./compiler/lua54.can:716 +for i = 2, # t do -- ./compiler/lua54.can:717 +local block = t[i] -- ./compiler/lua54.can:718 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 +end, -- ./compiler/lua54.can:723 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 +end, -- ./compiler/lua54.can:727 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 +end, -- ./compiler/lua54.can:731 +["Call"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 +local replacement = macro["replacement"] -- ./compiler/lua54.can:742 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 +macroargs["..."] = (function() -- ./compiler/lua54.can:746 +local self = {} -- ./compiler/lua54.can:746 +for j = i + 1, # t do -- ./compiler/lua54.can:746 +self[#self+1] = t[j] -- ./compiler/lua54.can:746 +end -- ./compiler/lua54.can:746 +return self -- ./compiler/lua54.can:746 +end)() -- ./compiler/lua54.can:746 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 +if t[i + 1] == nil then -- ./compiler/lua54.can:748 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 +end -- ./compiler/lua54.can:749 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 else -- ./compiler/lua54.can:751 -r = "" -- ./compiler/lua54.can:754 -end -- ./compiler/lua54.can:754 -return r -- ./compiler/lua54.can:756 -end, -- ./compiler/lua54.can:756 -["Id"] = function(t) -- ./compiler/lua54.can:759 -return t[1] -- ./compiler/lua54.can:760 -end, -- ./compiler/lua54.can:760 -["AttributeId"] = function(t) -- ./compiler/lua54.can:763 -if t[2] then -- ./compiler/lua54.can:764 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 -else -- ./compiler/lua54.can:765 -return t[1] -- ./compiler/lua54.can:767 -end -- ./compiler/lua54.can:767 -end, -- ./compiler/lua54.can:767 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 -if t["id"] then -- ./compiler/lua54.can:772 -return t["id"] -- ./compiler/lua54.can:773 -else -- ./compiler/lua54.can:773 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 -for j = 1, # t, 1 do -- ./compiler/lua54.can:777 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 -end -- ./compiler/lua54.can:778 -table["insert"](d, vars) -- ./compiler/lua54.can:780 -t["id"] = vars["id"] -- ./compiler/lua54.can:781 -return vars["id"] -- ./compiler/lua54.can:782 -end -- ./compiler/lua54.can:782 -end, -- ./compiler/lua54.can:782 -["Index"] = function(t) -- ./compiler/lua54.can:786 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 -else -- ./compiler/lua54.can:788 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +push("macroargs", macroargs) -- ./compiler/lua54.can:756 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 +local r = lua(replacement) -- ./compiler/lua54.can:758 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 +pop("macroargs") -- ./compiler/lua54.can:760 +return r -- ./compiler/lua54.can:761 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 +else -- ./compiler/lua54.can:764 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 +end -- ./compiler/lua54.can:766 +else -- ./compiler/lua54.can:766 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +end -- ./compiler/lua54.can:769 +end, -- ./compiler/lua54.can:769 +["SafeCall"] = function(t) -- ./compiler/lua54.can:773 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +else -- ./compiler/lua54.can:775 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +end -- ./compiler/lua54.can:777 +end, -- ./compiler/lua54.can:777 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 +if start == nil then start = 1 end -- ./compiler/lua54.can:782 +local r -- ./compiler/lua54.can:783 +if t[start] then -- ./compiler/lua54.can:784 +r = lua(t[start]) -- ./compiler/lua54.can:785 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 +end -- ./compiler/lua54.can:787 +else -- ./compiler/lua54.can:787 +r = "" -- ./compiler/lua54.can:790 end -- ./compiler/lua54.can:790 -end, -- ./compiler/lua54.can:790 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 -local l = {} -- ./compiler/lua54.can:796 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 -table["insert"](l, 1, t) -- ./compiler/lua54.can:798 -t = t[1] -- ./compiler/lua54.can:799 -end -- ./compiler/lua54.can:799 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 -for _, e in ipairs(l) do -- ./compiler/lua54.can:802 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 -else -- ./compiler/lua54.can:805 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +return r -- ./compiler/lua54.can:792 +end, -- ./compiler/lua54.can:792 +["Id"] = function(t) -- ./compiler/lua54.can:795 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 +local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:802 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 +local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 +return r -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 -return r -- ./compiler/lua54.can:811 -else -- ./compiler/lua54.can:811 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 -end -- ./compiler/lua54.can:813 -end, -- ./compiler/lua54.can:813 -["_opid"] = { -- ./compiler/lua54.can:818 -["add"] = "+", -- ./compiler/lua54.can:819 -["sub"] = "-", -- ./compiler/lua54.can:819 -["mul"] = "*", -- ./compiler/lua54.can:819 -["div"] = "/", -- ./compiler/lua54.can:819 -["idiv"] = "//", -- ./compiler/lua54.can:820 -["mod"] = "%", -- ./compiler/lua54.can:820 -["pow"] = "^", -- ./compiler/lua54.can:820 -["concat"] = "..", -- ./compiler/lua54.can:820 -["band"] = "&", -- ./compiler/lua54.can:821 -["bor"] = "|", -- ./compiler/lua54.can:821 -["bxor"] = "~", -- ./compiler/lua54.can:821 -["shl"] = "<<", -- ./compiler/lua54.can:821 -["shr"] = ">>", -- ./compiler/lua54.can:821 -["eq"] = "==", -- ./compiler/lua54.can:822 -["ne"] = "~=", -- ./compiler/lua54.can:822 -["lt"] = "<", -- ./compiler/lua54.can:822 -["gt"] = ">", -- ./compiler/lua54.can:822 -["le"] = "<=", -- ./compiler/lua54.can:822 -["ge"] = ">=", -- ./compiler/lua54.can:822 -["and"] = "and", -- ./compiler/lua54.can:823 -["or"] = "or", -- ./compiler/lua54.can:823 -["unm"] = "-", -- ./compiler/lua54.can:823 -["len"] = "#", -- ./compiler/lua54.can:823 -["bnot"] = "~", -- ./compiler/lua54.can:823 -["not"] = "not" -- ./compiler/lua54.can:823 -} -- ./compiler/lua54.can:823 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 -end }) -- ./compiler/lua54.can:827 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 -return requireStr .. code -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -local lua54 = _() or lua54 -- ./compiler/lua54.can:839 -package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:840 -local function _() -- ./compiler/lua54.can:843 -local function _() -- ./compiler/lua54.can:845 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 -return function(code, ast, options) -- ./compiler/lua54.can:3 -local lastInputPos = 1 -- ./compiler/lua54.can:5 -local prevLinePos = 1 -- ./compiler/lua54.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 -local lastLine = 1 -- ./compiler/lua54.can:8 -local indentLevel = 0 -- ./compiler/lua54.can:11 -local function newline() -- ./compiler/lua54.can:13 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 -if options["mapLines"] then -- ./compiler/lua54.can:15 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +return t[1] -- ./compiler/lua54.can:810 +end, -- ./compiler/lua54.can:810 +["AttributeId"] = function(t) -- ./compiler/lua54.can:813 +if t[2] then -- ./compiler/lua54.can:814 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 +else -- ./compiler/lua54.can:815 +return t[1] -- ./compiler/lua54.can:817 +end -- ./compiler/lua54.can:817 +end, -- ./compiler/lua54.can:817 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 +if t["id"] then -- ./compiler/lua54.can:822 +return t["id"] -- ./compiler/lua54.can:823 +else -- ./compiler/lua54.can:823 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 +for j = 1, # t, 1 do -- ./compiler/lua54.can:827 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 +end -- ./compiler/lua54.can:828 +table["insert"](d, vars) -- ./compiler/lua54.can:830 +t["id"] = vars["id"] -- ./compiler/lua54.can:831 +return vars["id"] -- ./compiler/lua54.can:832 +end -- ./compiler/lua54.can:832 +end, -- ./compiler/lua54.can:832 +["Index"] = function(t) -- ./compiler/lua54.can:836 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 +else -- ./compiler/lua54.can:838 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 +end -- ./compiler/lua54.can:840 +end, -- ./compiler/lua54.can:840 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 +local l = {} -- ./compiler/lua54.can:846 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 +table["insert"](l, 1, t) -- ./compiler/lua54.can:848 +t = t[1] -- ./compiler/lua54.can:849 +end -- ./compiler/lua54.can:849 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 +for _, e in ipairs(l) do -- ./compiler/lua54.can:852 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 +else -- ./compiler/lua54.can:855 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 +return r -- ./compiler/lua54.can:861 +else -- ./compiler/lua54.can:861 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 +end -- ./compiler/lua54.can:863 +end, -- ./compiler/lua54.can:863 +["_opid"] = { -- ./compiler/lua54.can:868 +["add"] = "+", -- ./compiler/lua54.can:869 +["sub"] = "-", -- ./compiler/lua54.can:869 +["mul"] = "*", -- ./compiler/lua54.can:869 +["div"] = "/", -- ./compiler/lua54.can:869 +["idiv"] = "//", -- ./compiler/lua54.can:870 +["mod"] = "%", -- ./compiler/lua54.can:870 +["pow"] = "^", -- ./compiler/lua54.can:870 +["concat"] = "..", -- ./compiler/lua54.can:870 +["band"] = "&", -- ./compiler/lua54.can:871 +["bor"] = "|", -- ./compiler/lua54.can:871 +["bxor"] = "~", -- ./compiler/lua54.can:871 +["shl"] = "<<", -- ./compiler/lua54.can:871 +["shr"] = ">>", -- ./compiler/lua54.can:871 +["eq"] = "==", -- ./compiler/lua54.can:872 +["ne"] = "~=", -- ./compiler/lua54.can:872 +["lt"] = "<", -- ./compiler/lua54.can:872 +["gt"] = ">", -- ./compiler/lua54.can:872 +["le"] = "<=", -- ./compiler/lua54.can:872 +["ge"] = ">=", -- ./compiler/lua54.can:872 +["and"] = "and", -- ./compiler/lua54.can:873 +["or"] = "or", -- ./compiler/lua54.can:873 +["unm"] = "-", -- ./compiler/lua54.can:873 +["len"] = "#", -- ./compiler/lua54.can:873 +["bnot"] = "~", -- ./compiler/lua54.can:873 +["not"] = "not" -- ./compiler/lua54.can:873 +} -- ./compiler/lua54.can:873 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 +end }) -- ./compiler/lua54.can:877 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 +return requireStr .. code -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +local lua54 = _() or lua54 -- ./compiler/lua54.can:889 +package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:890 +local function _() -- ./compiler/lua54.can:893 +local function _() -- ./compiler/lua54.can:895 +local util = require("candran.util") -- ./compiler/lua54.can:1 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 +return function(code, ast, options, macros) -- ./compiler/lua54.can:5 +if macros == nil then macros = { -- ./compiler/lua54.can:5 +["functions"] = {}, -- ./compiler/lua54.can:5 +["variables"] = {} -- ./compiler/lua54.can:5 +} end -- ./compiler/lua54.can:5 +local lastInputPos = 1 -- ./compiler/lua54.can:7 +local prevLinePos = 1 -- ./compiler/lua54.can:8 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 +local lastLine = 1 -- ./compiler/lua54.can:10 +local indentLevel = 0 -- ./compiler/lua54.can:13 +local function newline() -- ./compiler/lua54.can:15 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 +if options["mapLines"] then -- ./compiler/lua54.can:17 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:17 -if source and line then -- ./compiler/lua54.can:19 -lastSource = source -- ./compiler/lua54.can:20 -lastLine = tonumber(line) -- ./compiler/lua54.can:21 -else -- ./compiler/lua54.can:21 +") -- ./compiler/lua54.can:19 +if source and line then -- ./compiler/lua54.can:21 +lastSource = source -- ./compiler/lua54.can:22 +lastLine = tonumber(line) -- ./compiler/lua54.can:23 +else -- ./compiler/lua54.can:23 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:23 -lastLine = lastLine + (1) -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -prevLinePos = lastInputPos -- ./compiler/lua54.can:28 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 -end -- ./compiler/lua54.can:30 -return r -- ./compiler/lua54.can:32 +") do -- ./compiler/lua54.can:25 +lastLine = lastLine + (1) -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +prevLinePos = lastInputPos -- ./compiler/lua54.can:30 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 end -- ./compiler/lua54.can:32 -local function indent() -- ./compiler/lua54.can:35 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 -return newline() -- ./compiler/lua54.can:37 -end -- ./compiler/lua54.can:37 -local function unindent() -- ./compiler/lua54.can:40 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 -return newline() -- ./compiler/lua54.can:42 -end -- ./compiler/lua54.can:42 -local states = { -- ./compiler/lua54.can:47 -["push"] = {}, -- ./compiler/lua54.can:48 -["destructuring"] = {}, -- ./compiler/lua54.can:49 -["scope"] = {} -- ./compiler/lua54.can:50 -} -- ./compiler/lua54.can:50 -local function push(name, state) -- ./compiler/lua54.can:53 -table["insert"](states[name], state) -- ./compiler/lua54.can:54 -return "" -- ./compiler/lua54.can:55 -end -- ./compiler/lua54.can:55 -local function pop(name) -- ./compiler/lua54.can:58 -table["remove"](states[name]) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function set(name, state) -- ./compiler/lua54.can:63 -states[name][# states[name]] = state -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function peek(name) -- ./compiler/lua54.can:68 -return states[name][# states[name]] -- ./compiler/lua54.can:69 -end -- ./compiler/lua54.can:69 -local function var(name) -- ./compiler/lua54.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 -end -- ./compiler/lua54.can:75 -local function tmp() -- ./compiler/lua54.can:79 -local scope = peek("scope") -- ./compiler/lua54.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 -table["insert"](scope, var) -- ./compiler/lua54.can:82 -return var -- ./compiler/lua54.can:83 -end -- ./compiler/lua54.can:83 -local required = {} -- ./compiler/lua54.can:87 -local requireStr = "" -- ./compiler/lua54.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 -if not required[req] then -- ./compiler/lua54.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 -required[req] = true -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -local loop = { -- ./compiler/lua54.can:99 -"While", -- ./compiler/lua54.can:99 -"Repeat", -- ./compiler/lua54.can:99 -"Fornum", -- ./compiler/lua54.can:99 -"Forin", -- ./compiler/lua54.can:99 -"WhileExpr", -- ./compiler/lua54.can:99 -"RepeatExpr", -- ./compiler/lua54.can:99 -"FornumExpr", -- ./compiler/lua54.can:99 -"ForinExpr" -- ./compiler/lua54.can:99 -} -- ./compiler/lua54.can:99 -local func = { -- ./compiler/lua54.can:100 -"Function", -- ./compiler/lua54.can:100 -"TableCompr", -- ./compiler/lua54.can:100 -"DoExpr", -- ./compiler/lua54.can:100 -"WhileExpr", -- ./compiler/lua54.can:100 -"RepeatExpr", -- ./compiler/lua54.can:100 -"IfExpr", -- ./compiler/lua54.can:100 -"FornumExpr", -- ./compiler/lua54.can:100 -"ForinExpr" -- ./compiler/lua54.can:100 -} -- ./compiler/lua54.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 -local tagsCheck = {} -- ./compiler/lua54.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 -tagsCheck[tag] = true -- ./compiler/lua54.can:107 -end -- ./compiler/lua54.can:107 -local nofollowCheck = {} -- ./compiler/lua54.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 -nofollowCheck[tag] = true -- ./compiler/lua54.can:111 -end -- ./compiler/lua54.can:111 -for _, node in ipairs(list) do -- ./compiler/lua54.can:113 -if type(node) == "table" then -- ./compiler/lua54.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 -return node -- ./compiler/lua54.can:116 -end -- ./compiler/lua54.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 -if r then -- ./compiler/lua54.can:120 -return r -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -return nil -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 -local tagsCheck = {} -- ./compiler/lua54.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 -tagsCheck[tag] = true -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local nofollowCheck = {} -- ./compiler/lua54.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 -nofollowCheck[tag] = true -- ./compiler/lua54.can:136 -end -- ./compiler/lua54.can:136 -local found = {} -- ./compiler/lua54.can:138 -for _, node in ipairs(list) do -- ./compiler/lua54.can:139 -if type(node) == "table" then -- ./compiler/lua54.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 -table["insert"](found, n) -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 -table["insert"](found, node) -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -return found -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -local function all(list, tags) -- ./compiler/lua54.can:155 -for _, node in ipairs(list) do -- ./compiler/lua54.can:156 -local ok = false -- ./compiler/lua54.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 -if node["tag"] == tag then -- ./compiler/lua54.can:159 -ok = true -- ./compiler/lua54.can:160 -break -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -if not ok then -- ./compiler/lua54.can:164 -return false -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -return true -- ./compiler/lua54.can:168 -end -- ./compiler/lua54.can:168 -local tags -- ./compiler/lua54.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 -end -- ./compiler/lua54.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 -end -- ./compiler/lua54.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local CONTINUE_START = function() -- ./compiler/lua54.can:188 -return "do" .. indent() -- ./compiler/lua54.can:189 +return r -- ./compiler/lua54.can:34 +end -- ./compiler/lua54.can:34 +local function indent() -- ./compiler/lua54.can:37 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 +return newline() -- ./compiler/lua54.can:39 +end -- ./compiler/lua54.can:39 +local function unindent() -- ./compiler/lua54.can:42 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 +return newline() -- ./compiler/lua54.can:44 +end -- ./compiler/lua54.can:44 +local states = { -- ./compiler/lua54.can:49 +["push"] = {}, -- ./compiler/lua54.can:50 +["destructuring"] = {}, -- ./compiler/lua54.can:51 +["scope"] = {}, -- ./compiler/lua54.can:52 +["macroargs"] = {} -- ./compiler/lua54.can:53 +} -- ./compiler/lua54.can:53 +local function push(name, state) -- ./compiler/lua54.can:56 +table["insert"](states[name], state) -- ./compiler/lua54.can:57 +return "" -- ./compiler/lua54.can:58 +end -- ./compiler/lua54.can:58 +local function pop(name) -- ./compiler/lua54.can:61 +table["remove"](states[name]) -- ./compiler/lua54.can:62 +return "" -- ./compiler/lua54.can:63 +end -- ./compiler/lua54.can:63 +local function set(name, state) -- ./compiler/lua54.can:66 +states[name][# states[name]] = state -- ./compiler/lua54.can:67 +return "" -- ./compiler/lua54.can:68 +end -- ./compiler/lua54.can:68 +local function peek(name) -- ./compiler/lua54.can:71 +return states[name][# states[name]] -- ./compiler/lua54.can:72 +end -- ./compiler/lua54.can:72 +local function var(name) -- ./compiler/lua54.can:77 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 +end -- ./compiler/lua54.can:78 +local function tmp() -- ./compiler/lua54.can:82 +local scope = peek("scope") -- ./compiler/lua54.can:83 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 +table["insert"](scope, var) -- ./compiler/lua54.can:85 +return var -- ./compiler/lua54.can:86 +end -- ./compiler/lua54.can:86 +local nomacro = { -- ./compiler/lua54.can:90 +["variables"] = {}, -- ./compiler/lua54.can:90 +["functions"] = {} -- ./compiler/lua54.can:90 +} -- ./compiler/lua54.can:90 +local required = {} -- ./compiler/lua54.can:93 +local requireStr = "" -- ./compiler/lua54.can:94 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 +if not required[req] then -- ./compiler/lua54.can:98 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 +required[req] = true -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +local loop = { -- ./compiler/lua54.can:105 +"While", -- ./compiler/lua54.can:105 +"Repeat", -- ./compiler/lua54.can:105 +"Fornum", -- ./compiler/lua54.can:105 +"Forin", -- ./compiler/lua54.can:105 +"WhileExpr", -- ./compiler/lua54.can:105 +"RepeatExpr", -- ./compiler/lua54.can:105 +"FornumExpr", -- ./compiler/lua54.can:105 +"ForinExpr" -- ./compiler/lua54.can:105 +} -- ./compiler/lua54.can:105 +local func = { -- ./compiler/lua54.can:106 +"Function", -- ./compiler/lua54.can:106 +"TableCompr", -- ./compiler/lua54.can:106 +"DoExpr", -- ./compiler/lua54.can:106 +"WhileExpr", -- ./compiler/lua54.can:106 +"RepeatExpr", -- ./compiler/lua54.can:106 +"IfExpr", -- ./compiler/lua54.can:106 +"FornumExpr", -- ./compiler/lua54.can:106 +"ForinExpr" -- ./compiler/lua54.can:106 +} -- ./compiler/lua54.can:106 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 +local tagsCheck = {} -- ./compiler/lua54.can:111 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 +tagsCheck[tag] = true -- ./compiler/lua54.can:113 +end -- ./compiler/lua54.can:113 +local nofollowCheck = {} -- ./compiler/lua54.can:115 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 +nofollowCheck[tag] = true -- ./compiler/lua54.can:117 +end -- ./compiler/lua54.can:117 +for _, node in ipairs(list) do -- ./compiler/lua54.can:119 +if type(node) == "table" then -- ./compiler/lua54.can:120 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 +return node -- ./compiler/lua54.can:122 +end -- ./compiler/lua54.can:122 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 +if r then -- ./compiler/lua54.can:126 +return r -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +return nil -- ./compiler/lua54.can:130 +end -- ./compiler/lua54.can:130 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 +local tagsCheck = {} -- ./compiler/lua54.can:136 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 +tagsCheck[tag] = true -- ./compiler/lua54.can:138 +end -- ./compiler/lua54.can:138 +local nofollowCheck = {} -- ./compiler/lua54.can:140 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 +nofollowCheck[tag] = true -- ./compiler/lua54.can:142 +end -- ./compiler/lua54.can:142 +local found = {} -- ./compiler/lua54.can:144 +for _, node in ipairs(list) do -- ./compiler/lua54.can:145 +if type(node) == "table" then -- ./compiler/lua54.can:146 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 +table["insert"](found, n) -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 +table["insert"](found, node) -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +return found -- ./compiler/lua54.can:157 +end -- ./compiler/lua54.can:157 +local function all(list, tags) -- ./compiler/lua54.can:161 +for _, node in ipairs(list) do -- ./compiler/lua54.can:162 +local ok = false -- ./compiler/lua54.can:163 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 +if node["tag"] == tag then -- ./compiler/lua54.can:165 +ok = true -- ./compiler/lua54.can:166 +break -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +if not ok then -- ./compiler/lua54.can:170 +return false -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +return true -- ./compiler/lua54.can:174 +end -- ./compiler/lua54.can:174 +local tags -- ./compiler/lua54.can:178 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 +end -- ./compiler/lua54.can:182 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +end -- ./compiler/lua54.can:184 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 end -- ./compiler/lua54.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 end -- ./compiler/lua54.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 -local vars = {} -- ./compiler/lua54.can:195 -local values = {} -- ./compiler/lua54.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 -for _, v in ipairs(list) do -- ./compiler/lua54.can:198 -local var, val -- ./compiler/lua54.can:199 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 -var = v -- ./compiler/lua54.can:201 -val = { -- ./compiler/lua54.can:202 -["tag"] = "Index", -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "Id", -- ./compiler/lua54.can:202 -list["id"] -- ./compiler/lua54.can:202 -}, -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "String", -- ./compiler/lua54.can:202 -v[1] -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 -var = v[2] -- ./compiler/lua54.can:204 -val = { -- ./compiler/lua54.can:205 -["tag"] = "Index", -- ./compiler/lua54.can:205 -{ -- ./compiler/lua54.can:205 -["tag"] = "Id", -- ./compiler/lua54.can:205 -list["id"] -- ./compiler/lua54.can:205 -}, -- ./compiler/lua54.can:205 -v[1] -- ./compiler/lua54.can:205 -} -- ./compiler/lua54.can:205 -else -- ./compiler/lua54.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 -end -- ./compiler/lua54.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["rightOp"], -- ./compiler/lua54.can:210 -var, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["leftOp"], -- ./compiler/lua54.can:210 -val, -- ./compiler/lua54.can:210 -var -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 -val = { -- ./compiler/lua54.can:212 -["tag"] = "Op", -- ./compiler/lua54.can:212 -destructured["rightOp"], -- ./compiler/lua54.can:212 -var, -- ./compiler/lua54.can:212 -val -- ./compiler/lua54.can:212 -} -- ./compiler/lua54.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 -val = { -- ./compiler/lua54.can:214 -["tag"] = "Op", -- ./compiler/lua54.can:214 -destructured["leftOp"], -- ./compiler/lua54.can:214 -val, -- ./compiler/lua54.can:214 -var -- ./compiler/lua54.can:214 -} -- ./compiler/lua54.can:214 -end -- ./compiler/lua54.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -if # vars > 0 then -- ./compiler/lua54.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 -if newlineAfter then -- ./compiler/lua54.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 -else -- ./compiler/lua54.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -else -- ./compiler/lua54.can:225 -return "" -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -tags = setmetatable({ -- ./compiler/lua54.can:233 -["Block"] = function(t) -- ./compiler/lua54.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 -hasPush = false -- ./compiler/lua54.can:239 -end -- ./compiler/lua54.can:239 -local r = push("scope", {}) -- ./compiler/lua54.can:241 -if hasPush then -- ./compiler/lua54.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 -end -- ./compiler/lua54.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 -end -- ./compiler/lua54.can:246 -if t[# t] then -- ./compiler/lua54.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +local CONTINUE_START = function() -- ./compiler/lua54.can:194 +return "do" .. indent() -- ./compiler/lua54.can:195 +end -- ./compiler/lua54.can:195 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 +end -- ./compiler/lua54.can:198 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 +local vars = {} -- ./compiler/lua54.can:201 +local values = {} -- ./compiler/lua54.can:202 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 +for _, v in ipairs(list) do -- ./compiler/lua54.can:204 +local var, val -- ./compiler/lua54.can:205 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 +var = v -- ./compiler/lua54.can:207 +val = { -- ./compiler/lua54.can:208 +["tag"] = "Index", -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "Id", -- ./compiler/lua54.can:208 +list["id"] -- ./compiler/lua54.can:208 +}, -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "String", -- ./compiler/lua54.can:208 +v[1] -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 +var = v[2] -- ./compiler/lua54.can:210 +val = { -- ./compiler/lua54.can:211 +["tag"] = "Index", -- ./compiler/lua54.can:211 +{ -- ./compiler/lua54.can:211 +["tag"] = "Id", -- ./compiler/lua54.can:211 +list["id"] -- ./compiler/lua54.can:211 +}, -- ./compiler/lua54.can:211 +v[1] -- ./compiler/lua54.can:211 +} -- ./compiler/lua54.can:211 +else -- ./compiler/lua54.can:211 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 +end -- ./compiler/lua54.can:213 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 +val = { -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["rightOp"], -- ./compiler/lua54.can:216 +var, -- ./compiler/lua54.can:216 +{ -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["leftOp"], -- ./compiler/lua54.can:216 +val, -- ./compiler/lua54.can:216 +var -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +val = { -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["rightOp"], -- ./compiler/lua54.can:218 +var, -- ./compiler/lua54.can:218 +val -- ./compiler/lua54.can:218 +} -- ./compiler/lua54.can:218 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +val = { -- ./compiler/lua54.can:220 +["tag"] = "Op", -- ./compiler/lua54.can:220 +destructured["leftOp"], -- ./compiler/lua54.can:220 +val, -- ./compiler/lua54.can:220 +var -- ./compiler/lua54.can:220 +} -- ./compiler/lua54.can:220 +end -- ./compiler/lua54.can:220 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +if # vars > 0 then -- ./compiler/lua54.can:226 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 +if newlineAfter then -- ./compiler/lua54.can:228 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 +else -- ./compiler/lua54.can:229 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 +end -- ./compiler/lua54.can:231 +else -- ./compiler/lua54.can:231 +return "" -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +tags = setmetatable({ -- ./compiler/lua54.can:239 +["Block"] = function(t) -- ./compiler/lua54.can:241 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 +hasPush = false -- ./compiler/lua54.can:245 +end -- ./compiler/lua54.can:245 +local r = push("scope", {}) -- ./compiler/lua54.can:247 +if hasPush then -- ./compiler/lua54.can:248 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 end -- ./compiler/lua54.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 end -- ./compiler/lua54.can:252 -return r .. pop("scope") -- ./compiler/lua54.can:254 -end, -- ./compiler/lua54.can:254 -["Do"] = function(t) -- ./compiler/lua54.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 -end, -- ./compiler/lua54.can:261 -["Set"] = function(t) -- ./compiler/lua54.can:264 -local expr = t[# t] -- ./compiler/lua54.can:266 -local vars, values = {}, {} -- ./compiler/lua54.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 -else -- ./compiler/lua54.can:272 -table["insert"](vars, n) -- ./compiler/lua54.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 -local r = "" -- ./compiler/lua54.can:280 -if # vars > 0 then -- ./compiler/lua54.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 -end -- ./compiler/lua54.can:282 -if # destructuringVars > 0 then -- ./compiler/lua54.can:284 -local destructured = {} -- ./compiler/lua54.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 -end -- ./compiler/lua54.can:287 -return r -- ./compiler/lua54.can:289 -elseif # t == 4 then -- ./compiler/lua54.can:290 -if t[3] == "=" then -- ./compiler/lua54.can:291 -local r = "" -- ./compiler/lua54.can:292 -if # vars > 0 then -- ./compiler/lua54.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 -t[2], -- ./compiler/lua54.can:294 -vars[1], -- ./compiler/lua54.can:294 -{ -- ./compiler/lua54.can:294 -["tag"] = "Paren", -- ./compiler/lua54.can:294 -values[1] -- ./compiler/lua54.can:294 -} -- ./compiler/lua54.can:294 -}, "Op")) -- ./compiler/lua54.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 -t[2], -- ./compiler/lua54.can:296 -vars[i], -- ./compiler/lua54.can:296 -{ -- ./compiler/lua54.can:296 -["tag"] = "Paren", -- ./compiler/lua54.can:296 -values[i] -- ./compiler/lua54.can:296 -} -- ./compiler/lua54.can:296 -}, "Op")) -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -if # destructuringVars > 0 then -- ./compiler/lua54.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +if t[# t] then -- ./compiler/lua54.can:254 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 +end -- ./compiler/lua54.can:255 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 +end -- ./compiler/lua54.can:258 +return r .. pop("scope") -- ./compiler/lua54.can:260 +end, -- ./compiler/lua54.can:260 +["Do"] = function(t) -- ./compiler/lua54.can:266 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 +end, -- ./compiler/lua54.can:267 +["Set"] = function(t) -- ./compiler/lua54.can:270 +local expr = t[# t] -- ./compiler/lua54.can:272 +local vars, values = {}, {} -- ./compiler/lua54.can:273 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 +else -- ./compiler/lua54.can:278 +table["insert"](vars, n) -- ./compiler/lua54.can:280 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 +local r = "" -- ./compiler/lua54.can:286 +if # vars > 0 then -- ./compiler/lua54.can:287 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 +end -- ./compiler/lua54.can:288 +if # destructuringVars > 0 then -- ./compiler/lua54.can:290 +local destructured = {} -- ./compiler/lua54.can:291 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 +end -- ./compiler/lua54.can:293 +return r -- ./compiler/lua54.can:295 +elseif # t == 4 then -- ./compiler/lua54.can:296 +if t[3] == "=" then -- ./compiler/lua54.can:297 +local r = "" -- ./compiler/lua54.can:298 +if # vars > 0 then -- ./compiler/lua54.can:299 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 +t[2], -- ./compiler/lua54.can:300 +vars[1], -- ./compiler/lua54.can:300 +{ -- ./compiler/lua54.can:300 +["tag"] = "Paren", -- ./compiler/lua54.can:300 +values[1] -- ./compiler/lua54.can:300 +} -- ./compiler/lua54.can:300 +}, "Op")) -- ./compiler/lua54.can:300 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +t[2], -- ./compiler/lua54.can:302 +vars[i], -- ./compiler/lua54.can:302 +{ -- ./compiler/lua54.can:302 +["tag"] = "Paren", -- ./compiler/lua54.can:302 +values[i] -- ./compiler/lua54.can:302 +} -- ./compiler/lua54.can:302 +}, "Op")) -- ./compiler/lua54.can:302 end -- ./compiler/lua54.can:302 -return r -- ./compiler/lua54.can:304 -else -- ./compiler/lua54.can:304 -local r = "" -- ./compiler/lua54.can:306 -if # vars > 0 then -- ./compiler/lua54.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 -t[3], -- ./compiler/lua54.can:308 -{ -- ./compiler/lua54.can:308 -["tag"] = "Paren", -- ./compiler/lua54.can:308 -values[1] -- ./compiler/lua54.can:308 -}, -- ./compiler/lua54.can:308 -vars[1] -- ./compiler/lua54.can:308 -}, "Op")) -- ./compiler/lua54.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 -t[3], -- ./compiler/lua54.can:310 -{ -- ./compiler/lua54.can:310 -["tag"] = "Paren", -- ./compiler/lua54.can:310 -values[i] -- ./compiler/lua54.can:310 -}, -- ./compiler/lua54.can:310 -vars[i] -- ./compiler/lua54.can:310 -}, "Op")) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -if # destructuringVars > 0 then -- ./compiler/lua54.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:302 +if # destructuringVars > 0 then -- ./compiler/lua54.can:305 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 +end -- ./compiler/lua54.can:308 +return r -- ./compiler/lua54.can:310 +else -- ./compiler/lua54.can:310 +local r = "" -- ./compiler/lua54.can:312 +if # vars > 0 then -- ./compiler/lua54.can:313 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 +t[3], -- ./compiler/lua54.can:314 +{ -- ./compiler/lua54.can:314 +["tag"] = "Paren", -- ./compiler/lua54.can:314 +values[1] -- ./compiler/lua54.can:314 +}, -- ./compiler/lua54.can:314 +vars[1] -- ./compiler/lua54.can:314 +}, "Op")) -- ./compiler/lua54.can:314 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +t[3], -- ./compiler/lua54.can:316 +{ -- ./compiler/lua54.can:316 +["tag"] = "Paren", -- ./compiler/lua54.can:316 +values[i] -- ./compiler/lua54.can:316 +}, -- ./compiler/lua54.can:316 +vars[i] -- ./compiler/lua54.can:316 +}, "Op")) -- ./compiler/lua54.can:316 end -- ./compiler/lua54.can:316 -return r -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -else -- ./compiler/lua54.can:318 -local r = "" -- ./compiler/lua54.can:321 -if # vars > 0 then -- ./compiler/lua54.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 -t[2], -- ./compiler/lua54.can:323 -vars[1], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Op", -- ./compiler/lua54.can:323 -t[4], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Paren", -- ./compiler/lua54.can:323 -values[1] -- ./compiler/lua54.can:323 -}, -- ./compiler/lua54.can:323 -vars[1] -- ./compiler/lua54.can:323 -} -- ./compiler/lua54.can:323 -}, "Op")) -- ./compiler/lua54.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 -t[2], -- ./compiler/lua54.can:325 -vars[i], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Op", -- ./compiler/lua54.can:325 -t[4], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Paren", -- ./compiler/lua54.can:325 -values[i] -- ./compiler/lua54.can:325 -}, -- ./compiler/lua54.can:325 -vars[i] -- ./compiler/lua54.can:325 -} -- ./compiler/lua54.can:325 -}, "Op")) -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -if # destructuringVars > 0 then -- ./compiler/lua54.can:328 -local destructured = { -- ./compiler/lua54.can:329 -["rightOp"] = t[2], -- ./compiler/lua54.can:329 -["leftOp"] = t[4] -- ./compiler/lua54.can:329 +end -- ./compiler/lua54.can:316 +if # destructuringVars > 0 then -- ./compiler/lua54.can:319 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 +end -- ./compiler/lua54.can:322 +return r -- ./compiler/lua54.can:324 +end -- ./compiler/lua54.can:324 +else -- ./compiler/lua54.can:324 +local r = "" -- ./compiler/lua54.can:327 +if # vars > 0 then -- ./compiler/lua54.can:328 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 +t[2], -- ./compiler/lua54.can:329 +vars[1], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Op", -- ./compiler/lua54.can:329 +t[4], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Paren", -- ./compiler/lua54.can:329 +values[1] -- ./compiler/lua54.can:329 +}, -- ./compiler/lua54.can:329 +vars[1] -- ./compiler/lua54.can:329 } -- ./compiler/lua54.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:329 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +t[2], -- ./compiler/lua54.can:331 +vars[i], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Op", -- ./compiler/lua54.can:331 +t[4], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Paren", -- ./compiler/lua54.can:331 +values[i] -- ./compiler/lua54.can:331 +}, -- ./compiler/lua54.can:331 +vars[i] -- ./compiler/lua54.can:331 +} -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:331 end -- ./compiler/lua54.can:331 -return r -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end, -- ./compiler/lua54.can:333 -["While"] = function(t) -- ./compiler/lua54.can:337 -local r = "" -- ./compiler/lua54.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 -if # lets > 0 then -- ./compiler/lua54.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 -if # lets > 0 then -- ./compiler/lua54.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 -end -- ./compiler/lua54.can:349 -if hasContinue then -- ./compiler/lua54.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 -if hasContinue then -- ./compiler/lua54.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 -end -- ./compiler/lua54.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 -if # lets > 0 then -- ./compiler/lua54.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 -end -- ./compiler/lua54.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 -end -- ./compiler/lua54.can:363 -return r -- ./compiler/lua54.can:365 -end, -- ./compiler/lua54.can:365 -["Repeat"] = function(t) -- ./compiler/lua54.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 -local r = "repeat" .. indent() -- ./compiler/lua54.can:370 -if hasContinue then -- ./compiler/lua54.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 -end -- ./compiler/lua54.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 -if hasContinue then -- ./compiler/lua54.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 -end -- ./compiler/lua54.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 -return r -- ./compiler/lua54.can:379 -end, -- ./compiler/lua54.can:379 -["If"] = function(t) -- ./compiler/lua54.can:382 -local r = "" -- ./compiler/lua54.can:383 -local toClose = 0 -- ./compiler/lua54.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 -if # lets > 0 then -- ./compiler/lua54.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 -toClose = toClose + (1) -- ./compiler/lua54.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 -if # lets > 0 then -- ./compiler/lua54.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 -toClose = toClose + (1) -- ./compiler/lua54.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 -end -- ./compiler/lua54.can:400 -else -- ./compiler/lua54.can:400 -r = r .. ("else") -- ./compiler/lua54.can:403 -end -- ./compiler/lua54.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 -end -- ./compiler/lua54.can:405 -if # t % 2 == 1 then -- ./compiler/lua54.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -r = r .. ("end") -- ./compiler/lua54.can:410 -for i = 1, toClose do -- ./compiler/lua54.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 -end -- ./compiler/lua54.can:412 -return r -- ./compiler/lua54.can:414 -end, -- ./compiler/lua54.can:414 -["Fornum"] = function(t) -- ./compiler/lua54.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 -if # t == 5 then -- ./compiler/lua54.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 -if hasContinue then -- ./compiler/lua54.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 -end -- ./compiler/lua54.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 -if hasContinue then -- ./compiler/lua54.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 -end -- ./compiler/lua54.can:427 -return r .. unindent() .. "end" -- ./compiler/lua54.can:429 -else -- ./compiler/lua54.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 -if hasContinue then -- ./compiler/lua54.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 -end -- ./compiler/lua54.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 -if hasContinue then -- ./compiler/lua54.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 -end -- ./compiler/lua54.can:438 -return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:331 +if # destructuringVars > 0 then -- ./compiler/lua54.can:334 +local destructured = { -- ./compiler/lua54.can:335 +["rightOp"] = t[2], -- ./compiler/lua54.can:335 +["leftOp"] = t[4] -- ./compiler/lua54.can:335 +} -- ./compiler/lua54.can:335 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 +end -- ./compiler/lua54.can:337 +return r -- ./compiler/lua54.can:339 +end -- ./compiler/lua54.can:339 +end, -- ./compiler/lua54.can:339 +["While"] = function(t) -- ./compiler/lua54.can:343 +local r = "" -- ./compiler/lua54.can:344 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 +if # lets > 0 then -- ./compiler/lua54.can:347 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 +if # lets > 0 then -- ./compiler/lua54.can:354 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 +end -- ./compiler/lua54.can:355 +if hasContinue then -- ./compiler/lua54.can:357 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 +end -- ./compiler/lua54.can:358 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 +if hasContinue then -- ./compiler/lua54.can:361 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 +end -- ./compiler/lua54.can:362 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 +if # lets > 0 then -- ./compiler/lua54.can:365 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 +end -- ./compiler/lua54.can:367 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +end -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:371 +end, -- ./compiler/lua54.can:371 +["Repeat"] = function(t) -- ./compiler/lua54.can:374 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 +local r = "repeat" .. indent() -- ./compiler/lua54.can:376 +if hasContinue then -- ./compiler/lua54.can:377 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 +end -- ./compiler/lua54.can:378 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 +if hasContinue then -- ./compiler/lua54.can:381 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 +end -- ./compiler/lua54.can:382 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 +return r -- ./compiler/lua54.can:385 +end, -- ./compiler/lua54.can:385 +["If"] = function(t) -- ./compiler/lua54.can:388 +local r = "" -- ./compiler/lua54.can:389 +local toClose = 0 -- ./compiler/lua54.can:390 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 +if # lets > 0 then -- ./compiler/lua54.can:392 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 +toClose = toClose + (1) -- ./compiler/lua54.can:394 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 +if # lets > 0 then -- ./compiler/lua54.can:402 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 +toClose = toClose + (1) -- ./compiler/lua54.can:404 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 +end -- ./compiler/lua54.can:406 +else -- ./compiler/lua54.can:406 +r = r .. ("else") -- ./compiler/lua54.can:409 +end -- ./compiler/lua54.can:409 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +end -- ./compiler/lua54.can:411 +if # t % 2 == 1 then -- ./compiler/lua54.can:413 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 +end -- ./compiler/lua54.can:414 +r = r .. ("end") -- ./compiler/lua54.can:416 +for i = 1, toClose do -- ./compiler/lua54.can:417 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 +end -- ./compiler/lua54.can:418 +return r -- ./compiler/lua54.can:420 +end, -- ./compiler/lua54.can:420 +["Fornum"] = function(t) -- ./compiler/lua54.can:423 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 +if # t == 5 then -- ./compiler/lua54.can:425 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 +if hasContinue then -- ./compiler/lua54.can:428 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 +end -- ./compiler/lua54.can:429 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 +if hasContinue then -- ./compiler/lua54.can:432 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 +end -- ./compiler/lua54.can:433 +return r .. unindent() .. "end" -- ./compiler/lua54.can:435 +else -- ./compiler/lua54.can:435 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 +if hasContinue then -- ./compiler/lua54.can:439 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 end -- ./compiler/lua54.can:440 -end, -- ./compiler/lua54.can:440 -["Forin"] = function(t) -- ./compiler/lua54.can:444 -local destructured = {} -- ./compiler/lua54.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 -if hasContinue then -- ./compiler/lua54.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 -end -- ./compiler/lua54.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 -if hasContinue then -- ./compiler/lua54.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 -end -- ./compiler/lua54.can:453 -return r .. unindent() .. "end" -- ./compiler/lua54.can:455 -end, -- ./compiler/lua54.can:455 -["Local"] = function(t) -- ./compiler/lua54.can:458 -local destructured = {} -- ./compiler/lua54.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 -if t[2][1] then -- ./compiler/lua54.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 -end -- ./compiler/lua54.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 -end, -- ./compiler/lua54.can:464 -["Let"] = function(t) -- ./compiler/lua54.can:467 -local destructured = {} -- ./compiler/lua54.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 -local r = "local " .. nameList -- ./compiler/lua54.can:470 -if t[2][1] then -- ./compiler/lua54.can:471 -if all(t[2], { -- ./compiler/lua54.can:472 -"Nil", -- ./compiler/lua54.can:472 -"Dots", -- ./compiler/lua54.can:472 -"Boolean", -- ./compiler/lua54.can:472 -"Number", -- ./compiler/lua54.can:472 -"String" -- ./compiler/lua54.can:472 -}) then -- ./compiler/lua54.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 -else -- ./compiler/lua54.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 -end, -- ./compiler/lua54.can:478 -["Localrec"] = function(t) -- ./compiler/lua54.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 -end, -- ./compiler/lua54.can:482 -["Goto"] = function(t) -- ./compiler/lua54.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Label"] = function(t) -- ./compiler/lua54.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Return"] = function(t) -- ./compiler/lua54.can:493 -local push = peek("push") -- ./compiler/lua54.can:494 -if push then -- ./compiler/lua54.can:495 -local r = "" -- ./compiler/lua54.can:496 -for _, val in ipairs(t) do -- ./compiler/lua54.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 -end -- ./compiler/lua54.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 -else -- ./compiler/lua54.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 -end -- ./compiler/lua54.can:502 -end, -- ./compiler/lua54.can:502 -["Push"] = function(t) -- ./compiler/lua54.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 -r = "" -- ./compiler/lua54.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -if t[# t] then -- ./compiler/lua54.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 -else -- ./compiler/lua54.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 +if hasContinue then -- ./compiler/lua54.can:443 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 +end -- ./compiler/lua54.can:444 +return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +end -- ./compiler/lua54.can:446 +end, -- ./compiler/lua54.can:446 +["Forin"] = function(t) -- ./compiler/lua54.can:450 +local destructured = {} -- ./compiler/lua54.can:451 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 +if hasContinue then -- ./compiler/lua54.can:454 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 +end -- ./compiler/lua54.can:455 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 +if hasContinue then -- ./compiler/lua54.can:458 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 +end -- ./compiler/lua54.can:459 +return r .. unindent() .. "end" -- ./compiler/lua54.can:461 +end, -- ./compiler/lua54.can:461 +["Local"] = function(t) -- ./compiler/lua54.can:464 +local destructured = {} -- ./compiler/lua54.can:465 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 +if t[2][1] then -- ./compiler/lua54.can:467 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 +end -- ./compiler/lua54.can:468 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 +end, -- ./compiler/lua54.can:470 +["Let"] = function(t) -- ./compiler/lua54.can:473 +local destructured = {} -- ./compiler/lua54.can:474 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 +local r = "local " .. nameList -- ./compiler/lua54.can:476 +if t[2][1] then -- ./compiler/lua54.can:477 +if all(t[2], { -- ./compiler/lua54.can:478 +"Nil", -- ./compiler/lua54.can:478 +"Dots", -- ./compiler/lua54.can:478 +"Boolean", -- ./compiler/lua54.can:478 +"Number", -- ./compiler/lua54.can:478 +"String" -- ./compiler/lua54.can:478 +}) then -- ./compiler/lua54.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 +else -- ./compiler/lua54.can:479 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 +end, -- ./compiler/lua54.can:484 +["Localrec"] = function(t) -- ./compiler/lua54.can:487 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 +end, -- ./compiler/lua54.can:488 +["Goto"] = function(t) -- ./compiler/lua54.can:491 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 +end, -- ./compiler/lua54.can:492 +["Label"] = function(t) -- ./compiler/lua54.can:495 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 +end, -- ./compiler/lua54.can:496 +["Return"] = function(t) -- ./compiler/lua54.can:499 +local push = peek("push") -- ./compiler/lua54.can:500 +if push then -- ./compiler/lua54.can:501 +local r = "" -- ./compiler/lua54.can:502 +for _, val in ipairs(t) do -- ./compiler/lua54.can:503 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 +end -- ./compiler/lua54.can:504 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 +else -- ./compiler/lua54.can:506 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 +end -- ./compiler/lua54.can:508 +end, -- ./compiler/lua54.can:508 +["Push"] = function(t) -- ./compiler/lua54.can:512 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 +r = "" -- ./compiler/lua54.can:514 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 end -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -return r -- ./compiler/lua54.can:519 -end, -- ./compiler/lua54.can:519 -["Break"] = function() -- ./compiler/lua54.can:522 -return "break" -- ./compiler/lua54.can:523 -end, -- ./compiler/lua54.can:523 -["Continue"] = function() -- ./compiler/lua54.can:526 -return "goto " .. var("continue") -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Nil"] = function() -- ./compiler/lua54.can:534 -return "nil" -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Dots"] = function() -- ./compiler/lua54.can:538 -return "..." -- ./compiler/lua54.can:539 -end, -- ./compiler/lua54.can:539 -["Boolean"] = function(t) -- ./compiler/lua54.can:542 -return tostring(t[1]) -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Number"] = function(t) -- ./compiler/lua54.can:546 -return tostring(t[1]) -- ./compiler/lua54.can:547 -end, -- ./compiler/lua54.can:547 -["String"] = function(t) -- ./compiler/lua54.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 -end, -- ./compiler/lua54.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 -local r = "(" -- ./compiler/lua54.can:555 -local decl = {} -- ./compiler/lua54.can:556 -if t[1][1] then -- ./compiler/lua54.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 -r = r .. (id) -- ./compiler/lua54.can:563 -else -- ./compiler/lua54.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 -end -- ./compiler/lua54.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 -r = r .. (", " .. id) -- ./compiler/lua54.can:573 -else -- ./compiler/lua54.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 -r = r .. (d .. newline()) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 -end -- ./compiler/lua54.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 -if hasPush then -- ./compiler/lua54.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 -else -- ./compiler/lua54.can:588 -push("push", false) -- ./compiler/lua54.can:590 -end -- ./compiler/lua54.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 -end -- ./compiler/lua54.can:594 -pop("push") -- ./compiler/lua54.can:596 -return r .. unindent() .. "end" -- ./compiler/lua54.can:597 -end, -- ./compiler/lua54.can:597 -["Function"] = function(t) -- ./compiler/lua54.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 -end, -- ./compiler/lua54.can:600 -["Pair"] = function(t) -- ./compiler/lua54.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 -end, -- ./compiler/lua54.can:604 -["Table"] = function(t) -- ./compiler/lua54.can:606 -if # t == 0 then -- ./compiler/lua54.can:607 -return "{}" -- ./compiler/lua54.can:608 -elseif # t == 1 then -- ./compiler/lua54.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 -else -- ./compiler/lua54.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 -end -- ./compiler/lua54.can:612 -end, -- ./compiler/lua54.can:612 -["TableCompr"] = function(t) -- ./compiler/lua54.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 -end, -- ./compiler/lua54.can:617 -["Op"] = function(t) -- ./compiler/lua54.can:620 -local r -- ./compiler/lua54.can:621 -if # t == 2 then -- ./compiler/lua54.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +if t[# t] then -- ./compiler/lua54.can:518 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 +else -- ./compiler/lua54.can:520 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +return r -- ./compiler/lua54.can:525 +end, -- ./compiler/lua54.can:525 +["Break"] = function() -- ./compiler/lua54.can:528 +return "break" -- ./compiler/lua54.can:529 +end, -- ./compiler/lua54.can:529 +["Continue"] = function() -- ./compiler/lua54.can:532 +return "goto " .. var("continue") -- ./compiler/lua54.can:533 +end, -- ./compiler/lua54.can:533 +["Nil"] = function() -- ./compiler/lua54.can:540 +return "nil" -- ./compiler/lua54.can:541 +end, -- ./compiler/lua54.can:541 +["Dots"] = function() -- ./compiler/lua54.can:544 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 +return r -- ./compiler/lua54.can:550 +else -- ./compiler/lua54.can:550 +return "..." -- ./compiler/lua54.can:552 +end -- ./compiler/lua54.can:552 +end, -- ./compiler/lua54.can:552 +["Boolean"] = function(t) -- ./compiler/lua54.can:556 +return tostring(t[1]) -- ./compiler/lua54.can:557 +end, -- ./compiler/lua54.can:557 +["Number"] = function(t) -- ./compiler/lua54.can:560 +return tostring(t[1]) -- ./compiler/lua54.can:561 +end, -- ./compiler/lua54.can:561 +["String"] = function(t) -- ./compiler/lua54.can:564 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 +end, -- ./compiler/lua54.can:565 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 +local r = "(" -- ./compiler/lua54.can:569 +local decl = {} -- ./compiler/lua54.can:570 +if t[1][1] then -- ./compiler/lua54.can:571 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 +r = r .. (id) -- ./compiler/lua54.can:577 +else -- ./compiler/lua54.can:577 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 +end -- ./compiler/lua54.can:579 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 +r = r .. (", " .. id) -- ./compiler/lua54.can:587 +else -- ./compiler/lua54.can:587 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 +r = r .. (d .. newline()) -- ./compiler/lua54.can:595 +end -- ./compiler/lua54.can:595 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 +end -- ./compiler/lua54.can:598 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 +if hasPush then -- ./compiler/lua54.can:601 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 +else -- ./compiler/lua54.can:602 +push("push", false) -- ./compiler/lua54.can:604 +end -- ./compiler/lua54.can:604 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 +end -- ./compiler/lua54.can:608 +pop("push") -- ./compiler/lua54.can:610 +return r .. unindent() .. "end" -- ./compiler/lua54.can:611 +end, -- ./compiler/lua54.can:611 +["Function"] = function(t) -- ./compiler/lua54.can:613 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 +end, -- ./compiler/lua54.can:614 +["Pair"] = function(t) -- ./compiler/lua54.can:617 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 +end, -- ./compiler/lua54.can:618 +["Table"] = function(t) -- ./compiler/lua54.can:620 +if # t == 0 then -- ./compiler/lua54.can:621 +return "{}" -- ./compiler/lua54.can:622 +elseif # t == 1 then -- ./compiler/lua54.can:623 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 else -- ./compiler/lua54.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 end -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 -else -- ./compiler/lua54.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -return r -- ./compiler/lua54.can:635 -end, -- ./compiler/lua54.can:635 -["Paren"] = function(t) -- ./compiler/lua54.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 -end, -- ./compiler/lua54.can:639 -["MethodStub"] = function(t) -- ./compiler/lua54.can:642 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 -end, -- ./compiler/lua54.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 -end, -- ./compiler/lua54.can:658 -["LetExpr"] = function(t) -- ./compiler/lua54.can:665 -return lua(t[1][1]) -- ./compiler/lua54.can:666 -end, -- ./compiler/lua54.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 -local r = "(function()" .. indent() -- ./compiler/lua54.can:672 -if hasPush then -- ./compiler/lua54.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 -else -- ./compiler/lua54.can:674 -push("push", false) -- ./compiler/lua54.can:676 -end -- ./compiler/lua54.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 -if hasPush then -- ./compiler/lua54.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 -end -- ./compiler/lua54.can:680 -pop("push") -- ./compiler/lua54.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 -return r -- ./compiler/lua54.can:684 -end, -- ./compiler/lua54.can:684 -["DoExpr"] = function(t) -- ./compiler/lua54.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 -end -- ./compiler/lua54.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 -end, -- ./compiler/lua54.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 -end, -- ./compiler/lua54.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 -end, -- ./compiler/lua54.can:699 -["IfExpr"] = function(t) -- ./compiler/lua54.can:702 -for i = 2, # t do -- ./compiler/lua54.can:703 -local block = t[i] -- ./compiler/lua54.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:626 +["TableCompr"] = function(t) -- ./compiler/lua54.can:630 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 +end, -- ./compiler/lua54.can:631 +["Op"] = function(t) -- ./compiler/lua54.can:634 +local r -- ./compiler/lua54.can:635 +if # t == 2 then -- ./compiler/lua54.can:636 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 +else -- ./compiler/lua54.can:638 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 +end -- ./compiler/lua54.can:640 +else -- ./compiler/lua54.can:640 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 +else -- ./compiler/lua54.can:644 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +return r -- ./compiler/lua54.can:649 +end, -- ./compiler/lua54.can:649 +["Paren"] = function(t) -- ./compiler/lua54.can:652 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 +end, -- ./compiler/lua54.can:653 +["MethodStub"] = function(t) -- ./compiler/lua54.can:656 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 +end, -- ./compiler/lua54.can:662 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 +end, -- ./compiler/lua54.can:672 +["LetExpr"] = function(t) -- ./compiler/lua54.can:679 +return lua(t[1][1]) -- ./compiler/lua54.can:680 +end, -- ./compiler/lua54.can:680 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 +local r = "(function()" .. indent() -- ./compiler/lua54.can:686 +if hasPush then -- ./compiler/lua54.can:687 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 +else -- ./compiler/lua54.can:688 +push("push", false) -- ./compiler/lua54.can:690 +end -- ./compiler/lua54.can:690 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 +if hasPush then -- ./compiler/lua54.can:693 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 +end -- ./compiler/lua54.can:694 +pop("push") -- ./compiler/lua54.can:696 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 +return r -- ./compiler/lua54.can:698 +end, -- ./compiler/lua54.can:698 +["DoExpr"] = function(t) -- ./compiler/lua54.can:701 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 +end -- ./compiler/lua54.can:703 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 +end, -- ./compiler/lua54.can:705 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 end, -- ./compiler/lua54.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 end, -- ./compiler/lua54.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 -end, -- ./compiler/lua54.can:717 -["Call"] = function(t) -- ./compiler/lua54.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 -else -- ./compiler/lua54.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 -end -- ./compiler/lua54.can:730 -else -- ./compiler/lua54.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 -end -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["SafeCall"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 -else -- ./compiler/lua54.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 -end -- ./compiler/lua54.can:741 -end, -- ./compiler/lua54.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 -if start == nil then start = 1 end -- ./compiler/lua54.can:746 -local r -- ./compiler/lua54.can:747 -if t[start] then -- ./compiler/lua54.can:748 -r = lua(t[start]) -- ./compiler/lua54.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 -end -- ./compiler/lua54.can:751 +["IfExpr"] = function(t) -- ./compiler/lua54.can:716 +for i = 2, # t do -- ./compiler/lua54.can:717 +local block = t[i] -- ./compiler/lua54.can:718 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 +end, -- ./compiler/lua54.can:723 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 +end, -- ./compiler/lua54.can:727 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 +end, -- ./compiler/lua54.can:731 +["Call"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 +local replacement = macro["replacement"] -- ./compiler/lua54.can:742 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 +macroargs["..."] = (function() -- ./compiler/lua54.can:746 +local self = {} -- ./compiler/lua54.can:746 +for j = i + 1, # t do -- ./compiler/lua54.can:746 +self[#self+1] = t[j] -- ./compiler/lua54.can:746 +end -- ./compiler/lua54.can:746 +return self -- ./compiler/lua54.can:746 +end)() -- ./compiler/lua54.can:746 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 +if t[i + 1] == nil then -- ./compiler/lua54.can:748 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 +end -- ./compiler/lua54.can:749 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 else -- ./compiler/lua54.can:751 -r = "" -- ./compiler/lua54.can:754 -end -- ./compiler/lua54.can:754 -return r -- ./compiler/lua54.can:756 -end, -- ./compiler/lua54.can:756 -["Id"] = function(t) -- ./compiler/lua54.can:759 -return t[1] -- ./compiler/lua54.can:760 -end, -- ./compiler/lua54.can:760 -["AttributeId"] = function(t) -- ./compiler/lua54.can:763 -if t[2] then -- ./compiler/lua54.can:764 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 -else -- ./compiler/lua54.can:765 -return t[1] -- ./compiler/lua54.can:767 -end -- ./compiler/lua54.can:767 -end, -- ./compiler/lua54.can:767 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 -if t["id"] then -- ./compiler/lua54.can:772 -return t["id"] -- ./compiler/lua54.can:773 -else -- ./compiler/lua54.can:773 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 -for j = 1, # t, 1 do -- ./compiler/lua54.can:777 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 -end -- ./compiler/lua54.can:778 -table["insert"](d, vars) -- ./compiler/lua54.can:780 -t["id"] = vars["id"] -- ./compiler/lua54.can:781 -return vars["id"] -- ./compiler/lua54.can:782 -end -- ./compiler/lua54.can:782 -end, -- ./compiler/lua54.can:782 -["Index"] = function(t) -- ./compiler/lua54.can:786 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 -else -- ./compiler/lua54.can:788 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +push("macroargs", macroargs) -- ./compiler/lua54.can:756 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 +local r = lua(replacement) -- ./compiler/lua54.can:758 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 +pop("macroargs") -- ./compiler/lua54.can:760 +return r -- ./compiler/lua54.can:761 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 +else -- ./compiler/lua54.can:764 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 +end -- ./compiler/lua54.can:766 +else -- ./compiler/lua54.can:766 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +end -- ./compiler/lua54.can:769 +end, -- ./compiler/lua54.can:769 +["SafeCall"] = function(t) -- ./compiler/lua54.can:773 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +else -- ./compiler/lua54.can:775 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +end -- ./compiler/lua54.can:777 +end, -- ./compiler/lua54.can:777 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 +if start == nil then start = 1 end -- ./compiler/lua54.can:782 +local r -- ./compiler/lua54.can:783 +if t[start] then -- ./compiler/lua54.can:784 +r = lua(t[start]) -- ./compiler/lua54.can:785 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 +end -- ./compiler/lua54.can:787 +else -- ./compiler/lua54.can:787 +r = "" -- ./compiler/lua54.can:790 end -- ./compiler/lua54.can:790 -end, -- ./compiler/lua54.can:790 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 -local l = {} -- ./compiler/lua54.can:796 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 -table["insert"](l, 1, t) -- ./compiler/lua54.can:798 -t = t[1] -- ./compiler/lua54.can:799 -end -- ./compiler/lua54.can:799 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 -for _, e in ipairs(l) do -- ./compiler/lua54.can:802 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 -else -- ./compiler/lua54.can:805 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +return r -- ./compiler/lua54.can:792 +end, -- ./compiler/lua54.can:792 +["Id"] = function(t) -- ./compiler/lua54.can:795 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 +local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:802 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 +local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 +return r -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 -return r -- ./compiler/lua54.can:811 -else -- ./compiler/lua54.can:811 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 -end -- ./compiler/lua54.can:813 -end, -- ./compiler/lua54.can:813 -["_opid"] = { -- ./compiler/lua54.can:818 -["add"] = "+", -- ./compiler/lua54.can:819 -["sub"] = "-", -- ./compiler/lua54.can:819 -["mul"] = "*", -- ./compiler/lua54.can:819 -["div"] = "/", -- ./compiler/lua54.can:819 -["idiv"] = "//", -- ./compiler/lua54.can:820 -["mod"] = "%", -- ./compiler/lua54.can:820 -["pow"] = "^", -- ./compiler/lua54.can:820 -["concat"] = "..", -- ./compiler/lua54.can:820 -["band"] = "&", -- ./compiler/lua54.can:821 -["bor"] = "|", -- ./compiler/lua54.can:821 -["bxor"] = "~", -- ./compiler/lua54.can:821 -["shl"] = "<<", -- ./compiler/lua54.can:821 -["shr"] = ">>", -- ./compiler/lua54.can:821 -["eq"] = "==", -- ./compiler/lua54.can:822 -["ne"] = "~=", -- ./compiler/lua54.can:822 -["lt"] = "<", -- ./compiler/lua54.can:822 -["gt"] = ">", -- ./compiler/lua54.can:822 -["le"] = "<=", -- ./compiler/lua54.can:822 -["ge"] = ">=", -- ./compiler/lua54.can:822 -["and"] = "and", -- ./compiler/lua54.can:823 -["or"] = "or", -- ./compiler/lua54.can:823 -["unm"] = "-", -- ./compiler/lua54.can:823 -["len"] = "#", -- ./compiler/lua54.can:823 -["bnot"] = "~", -- ./compiler/lua54.can:823 -["not"] = "not" -- ./compiler/lua54.can:823 -} -- ./compiler/lua54.can:823 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 -end }) -- ./compiler/lua54.can:827 +return t[1] -- ./compiler/lua54.can:810 +end, -- ./compiler/lua54.can:810 +["AttributeId"] = function(t) -- ./compiler/lua54.can:813 +if t[2] then -- ./compiler/lua54.can:814 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 +else -- ./compiler/lua54.can:815 +return t[1] -- ./compiler/lua54.can:817 +end -- ./compiler/lua54.can:817 +end, -- ./compiler/lua54.can:817 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 +if t["id"] then -- ./compiler/lua54.can:822 +return t["id"] -- ./compiler/lua54.can:823 +else -- ./compiler/lua54.can:823 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 +for j = 1, # t, 1 do -- ./compiler/lua54.can:827 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 +end -- ./compiler/lua54.can:828 +table["insert"](d, vars) -- ./compiler/lua54.can:830 +t["id"] = vars["id"] -- ./compiler/lua54.can:831 +return vars["id"] -- ./compiler/lua54.can:832 +end -- ./compiler/lua54.can:832 +end, -- ./compiler/lua54.can:832 +["Index"] = function(t) -- ./compiler/lua54.can:836 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 +else -- ./compiler/lua54.can:838 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 +end -- ./compiler/lua54.can:840 +end, -- ./compiler/lua54.can:840 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 +local l = {} -- ./compiler/lua54.can:846 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 +table["insert"](l, 1, t) -- ./compiler/lua54.can:848 +t = t[1] -- ./compiler/lua54.can:849 +end -- ./compiler/lua54.can:849 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 +for _, e in ipairs(l) do -- ./compiler/lua54.can:852 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 +else -- ./compiler/lua54.can:855 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 +return r -- ./compiler/lua54.can:861 +else -- ./compiler/lua54.can:861 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 +end -- ./compiler/lua54.can:863 +end, -- ./compiler/lua54.can:863 +["_opid"] = { -- ./compiler/lua54.can:868 +["add"] = "+", -- ./compiler/lua54.can:869 +["sub"] = "-", -- ./compiler/lua54.can:869 +["mul"] = "*", -- ./compiler/lua54.can:869 +["div"] = "/", -- ./compiler/lua54.can:869 +["idiv"] = "//", -- ./compiler/lua54.can:870 +["mod"] = "%", -- ./compiler/lua54.can:870 +["pow"] = "^", -- ./compiler/lua54.can:870 +["concat"] = "..", -- ./compiler/lua54.can:870 +["band"] = "&", -- ./compiler/lua54.can:871 +["bor"] = "|", -- ./compiler/lua54.can:871 +["bxor"] = "~", -- ./compiler/lua54.can:871 +["shl"] = "<<", -- ./compiler/lua54.can:871 +["shr"] = ">>", -- ./compiler/lua54.can:871 +["eq"] = "==", -- ./compiler/lua54.can:872 +["ne"] = "~=", -- ./compiler/lua54.can:872 +["lt"] = "<", -- ./compiler/lua54.can:872 +["gt"] = ">", -- ./compiler/lua54.can:872 +["le"] = "<=", -- ./compiler/lua54.can:872 +["ge"] = ">=", -- ./compiler/lua54.can:872 +["and"] = "and", -- ./compiler/lua54.can:873 +["or"] = "or", -- ./compiler/lua54.can:873 +["unm"] = "-", -- ./compiler/lua54.can:873 +["len"] = "#", -- ./compiler/lua54.can:873 +["bnot"] = "~", -- ./compiler/lua54.can:873 +["not"] = "not" -- ./compiler/lua54.can:873 +} -- ./compiler/lua54.can:873 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 +end }) -- ./compiler/lua54.can:877 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -1855,11 +1988,11 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 -return requireStr .. code -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 +return requireStr .. code -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +local lua54 = _() or lua54 -- ./compiler/lua54.can:889 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -1867,861 +2000,921 @@ package["loaded"]["compiler.lua53"] = lua53 or true -- ./compiler/lua53.can:23 local function _() -- ./compiler/lua53.can:26 local function _() -- ./compiler/lua53.can:28 local function _() -- ./compiler/lua53.can:30 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 -return function(code, ast, options) -- ./compiler/lua54.can:3 -local lastInputPos = 1 -- ./compiler/lua54.can:5 -local prevLinePos = 1 -- ./compiler/lua54.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 -local lastLine = 1 -- ./compiler/lua54.can:8 -local indentLevel = 0 -- ./compiler/lua54.can:11 -local function newline() -- ./compiler/lua54.can:13 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 -if options["mapLines"] then -- ./compiler/lua54.can:15 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local util = require("candran.util") -- ./compiler/lua54.can:1 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 +return function(code, ast, options, macros) -- ./compiler/lua54.can:5 +if macros == nil then macros = { -- ./compiler/lua54.can:5 +["functions"] = {}, -- ./compiler/lua54.can:5 +["variables"] = {} -- ./compiler/lua54.can:5 +} end -- ./compiler/lua54.can:5 +local lastInputPos = 1 -- ./compiler/lua54.can:7 +local prevLinePos = 1 -- ./compiler/lua54.can:8 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 +local lastLine = 1 -- ./compiler/lua54.can:10 +local indentLevel = 0 -- ./compiler/lua54.can:13 +local function newline() -- ./compiler/lua54.can:15 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 +if options["mapLines"] then -- ./compiler/lua54.can:17 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:17 -if source and line then -- ./compiler/lua54.can:19 -lastSource = source -- ./compiler/lua54.can:20 -lastLine = tonumber(line) -- ./compiler/lua54.can:21 -else -- ./compiler/lua54.can:21 +") -- ./compiler/lua54.can:19 +if source and line then -- ./compiler/lua54.can:21 +lastSource = source -- ./compiler/lua54.can:22 +lastLine = tonumber(line) -- ./compiler/lua54.can:23 +else -- ./compiler/lua54.can:23 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:23 -lastLine = lastLine + (1) -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -prevLinePos = lastInputPos -- ./compiler/lua54.can:28 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 -end -- ./compiler/lua54.can:30 -return r -- ./compiler/lua54.can:32 +") do -- ./compiler/lua54.can:25 +lastLine = lastLine + (1) -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +prevLinePos = lastInputPos -- ./compiler/lua54.can:30 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 end -- ./compiler/lua54.can:32 -local function indent() -- ./compiler/lua54.can:35 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 -return newline() -- ./compiler/lua54.can:37 -end -- ./compiler/lua54.can:37 -local function unindent() -- ./compiler/lua54.can:40 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 -return newline() -- ./compiler/lua54.can:42 -end -- ./compiler/lua54.can:42 -local states = { -- ./compiler/lua54.can:47 -["push"] = {}, -- ./compiler/lua54.can:48 -["destructuring"] = {}, -- ./compiler/lua54.can:49 -["scope"] = {} -- ./compiler/lua54.can:50 -} -- ./compiler/lua54.can:50 -local function push(name, state) -- ./compiler/lua54.can:53 -table["insert"](states[name], state) -- ./compiler/lua54.can:54 -return "" -- ./compiler/lua54.can:55 -end -- ./compiler/lua54.can:55 -local function pop(name) -- ./compiler/lua54.can:58 -table["remove"](states[name]) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function set(name, state) -- ./compiler/lua54.can:63 -states[name][# states[name]] = state -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function peek(name) -- ./compiler/lua54.can:68 -return states[name][# states[name]] -- ./compiler/lua54.can:69 -end -- ./compiler/lua54.can:69 -local function var(name) -- ./compiler/lua54.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 -end -- ./compiler/lua54.can:75 -local function tmp() -- ./compiler/lua54.can:79 -local scope = peek("scope") -- ./compiler/lua54.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 -table["insert"](scope, var) -- ./compiler/lua54.can:82 -return var -- ./compiler/lua54.can:83 -end -- ./compiler/lua54.can:83 -local required = {} -- ./compiler/lua54.can:87 -local requireStr = "" -- ./compiler/lua54.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 -if not required[req] then -- ./compiler/lua54.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 -required[req] = true -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -local loop = { -- ./compiler/lua54.can:99 -"While", -- ./compiler/lua54.can:99 -"Repeat", -- ./compiler/lua54.can:99 -"Fornum", -- ./compiler/lua54.can:99 -"Forin", -- ./compiler/lua54.can:99 -"WhileExpr", -- ./compiler/lua54.can:99 -"RepeatExpr", -- ./compiler/lua54.can:99 -"FornumExpr", -- ./compiler/lua54.can:99 -"ForinExpr" -- ./compiler/lua54.can:99 -} -- ./compiler/lua54.can:99 -local func = { -- ./compiler/lua54.can:100 -"Function", -- ./compiler/lua54.can:100 -"TableCompr", -- ./compiler/lua54.can:100 -"DoExpr", -- ./compiler/lua54.can:100 -"WhileExpr", -- ./compiler/lua54.can:100 -"RepeatExpr", -- ./compiler/lua54.can:100 -"IfExpr", -- ./compiler/lua54.can:100 -"FornumExpr", -- ./compiler/lua54.can:100 -"ForinExpr" -- ./compiler/lua54.can:100 -} -- ./compiler/lua54.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 -local tagsCheck = {} -- ./compiler/lua54.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 -tagsCheck[tag] = true -- ./compiler/lua54.can:107 -end -- ./compiler/lua54.can:107 -local nofollowCheck = {} -- ./compiler/lua54.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 -nofollowCheck[tag] = true -- ./compiler/lua54.can:111 -end -- ./compiler/lua54.can:111 -for _, node in ipairs(list) do -- ./compiler/lua54.can:113 -if type(node) == "table" then -- ./compiler/lua54.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 -return node -- ./compiler/lua54.can:116 -end -- ./compiler/lua54.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 -if r then -- ./compiler/lua54.can:120 -return r -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -return nil -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 -local tagsCheck = {} -- ./compiler/lua54.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 -tagsCheck[tag] = true -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local nofollowCheck = {} -- ./compiler/lua54.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 -nofollowCheck[tag] = true -- ./compiler/lua54.can:136 -end -- ./compiler/lua54.can:136 -local found = {} -- ./compiler/lua54.can:138 -for _, node in ipairs(list) do -- ./compiler/lua54.can:139 -if type(node) == "table" then -- ./compiler/lua54.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 -table["insert"](found, n) -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 -table["insert"](found, node) -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -return found -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -local function all(list, tags) -- ./compiler/lua54.can:155 -for _, node in ipairs(list) do -- ./compiler/lua54.can:156 -local ok = false -- ./compiler/lua54.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 -if node["tag"] == tag then -- ./compiler/lua54.can:159 -ok = true -- ./compiler/lua54.can:160 -break -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -if not ok then -- ./compiler/lua54.can:164 -return false -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -return true -- ./compiler/lua54.can:168 -end -- ./compiler/lua54.can:168 -local tags -- ./compiler/lua54.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 -end -- ./compiler/lua54.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 -end -- ./compiler/lua54.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local CONTINUE_START = function() -- ./compiler/lua54.can:188 -return "do" .. indent() -- ./compiler/lua54.can:189 +return r -- ./compiler/lua54.can:34 +end -- ./compiler/lua54.can:34 +local function indent() -- ./compiler/lua54.can:37 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 +return newline() -- ./compiler/lua54.can:39 +end -- ./compiler/lua54.can:39 +local function unindent() -- ./compiler/lua54.can:42 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 +return newline() -- ./compiler/lua54.can:44 +end -- ./compiler/lua54.can:44 +local states = { -- ./compiler/lua54.can:49 +["push"] = {}, -- ./compiler/lua54.can:50 +["destructuring"] = {}, -- ./compiler/lua54.can:51 +["scope"] = {}, -- ./compiler/lua54.can:52 +["macroargs"] = {} -- ./compiler/lua54.can:53 +} -- ./compiler/lua54.can:53 +local function push(name, state) -- ./compiler/lua54.can:56 +table["insert"](states[name], state) -- ./compiler/lua54.can:57 +return "" -- ./compiler/lua54.can:58 +end -- ./compiler/lua54.can:58 +local function pop(name) -- ./compiler/lua54.can:61 +table["remove"](states[name]) -- ./compiler/lua54.can:62 +return "" -- ./compiler/lua54.can:63 +end -- ./compiler/lua54.can:63 +local function set(name, state) -- ./compiler/lua54.can:66 +states[name][# states[name]] = state -- ./compiler/lua54.can:67 +return "" -- ./compiler/lua54.can:68 +end -- ./compiler/lua54.can:68 +local function peek(name) -- ./compiler/lua54.can:71 +return states[name][# states[name]] -- ./compiler/lua54.can:72 +end -- ./compiler/lua54.can:72 +local function var(name) -- ./compiler/lua54.can:77 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 +end -- ./compiler/lua54.can:78 +local function tmp() -- ./compiler/lua54.can:82 +local scope = peek("scope") -- ./compiler/lua54.can:83 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 +table["insert"](scope, var) -- ./compiler/lua54.can:85 +return var -- ./compiler/lua54.can:86 +end -- ./compiler/lua54.can:86 +local nomacro = { -- ./compiler/lua54.can:90 +["variables"] = {}, -- ./compiler/lua54.can:90 +["functions"] = {} -- ./compiler/lua54.can:90 +} -- ./compiler/lua54.can:90 +local required = {} -- ./compiler/lua54.can:93 +local requireStr = "" -- ./compiler/lua54.can:94 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 +if not required[req] then -- ./compiler/lua54.can:98 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 +required[req] = true -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +local loop = { -- ./compiler/lua54.can:105 +"While", -- ./compiler/lua54.can:105 +"Repeat", -- ./compiler/lua54.can:105 +"Fornum", -- ./compiler/lua54.can:105 +"Forin", -- ./compiler/lua54.can:105 +"WhileExpr", -- ./compiler/lua54.can:105 +"RepeatExpr", -- ./compiler/lua54.can:105 +"FornumExpr", -- ./compiler/lua54.can:105 +"ForinExpr" -- ./compiler/lua54.can:105 +} -- ./compiler/lua54.can:105 +local func = { -- ./compiler/lua54.can:106 +"Function", -- ./compiler/lua54.can:106 +"TableCompr", -- ./compiler/lua54.can:106 +"DoExpr", -- ./compiler/lua54.can:106 +"WhileExpr", -- ./compiler/lua54.can:106 +"RepeatExpr", -- ./compiler/lua54.can:106 +"IfExpr", -- ./compiler/lua54.can:106 +"FornumExpr", -- ./compiler/lua54.can:106 +"ForinExpr" -- ./compiler/lua54.can:106 +} -- ./compiler/lua54.can:106 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 +local tagsCheck = {} -- ./compiler/lua54.can:111 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 +tagsCheck[tag] = true -- ./compiler/lua54.can:113 +end -- ./compiler/lua54.can:113 +local nofollowCheck = {} -- ./compiler/lua54.can:115 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 +nofollowCheck[tag] = true -- ./compiler/lua54.can:117 +end -- ./compiler/lua54.can:117 +for _, node in ipairs(list) do -- ./compiler/lua54.can:119 +if type(node) == "table" then -- ./compiler/lua54.can:120 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 +return node -- ./compiler/lua54.can:122 +end -- ./compiler/lua54.can:122 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 +if r then -- ./compiler/lua54.can:126 +return r -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +return nil -- ./compiler/lua54.can:130 +end -- ./compiler/lua54.can:130 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 +local tagsCheck = {} -- ./compiler/lua54.can:136 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 +tagsCheck[tag] = true -- ./compiler/lua54.can:138 +end -- ./compiler/lua54.can:138 +local nofollowCheck = {} -- ./compiler/lua54.can:140 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 +nofollowCheck[tag] = true -- ./compiler/lua54.can:142 +end -- ./compiler/lua54.can:142 +local found = {} -- ./compiler/lua54.can:144 +for _, node in ipairs(list) do -- ./compiler/lua54.can:145 +if type(node) == "table" then -- ./compiler/lua54.can:146 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 +table["insert"](found, n) -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 +table["insert"](found, node) -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +return found -- ./compiler/lua54.can:157 +end -- ./compiler/lua54.can:157 +local function all(list, tags) -- ./compiler/lua54.can:161 +for _, node in ipairs(list) do -- ./compiler/lua54.can:162 +local ok = false -- ./compiler/lua54.can:163 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 +if node["tag"] == tag then -- ./compiler/lua54.can:165 +ok = true -- ./compiler/lua54.can:166 +break -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +if not ok then -- ./compiler/lua54.can:170 +return false -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +return true -- ./compiler/lua54.can:174 +end -- ./compiler/lua54.can:174 +local tags -- ./compiler/lua54.can:178 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 +end -- ./compiler/lua54.can:182 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +end -- ./compiler/lua54.can:184 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 end -- ./compiler/lua54.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 end -- ./compiler/lua54.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 -local vars = {} -- ./compiler/lua54.can:195 -local values = {} -- ./compiler/lua54.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 -for _, v in ipairs(list) do -- ./compiler/lua54.can:198 -local var, val -- ./compiler/lua54.can:199 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 -var = v -- ./compiler/lua54.can:201 -val = { -- ./compiler/lua54.can:202 -["tag"] = "Index", -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "Id", -- ./compiler/lua54.can:202 -list["id"] -- ./compiler/lua54.can:202 -}, -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "String", -- ./compiler/lua54.can:202 -v[1] -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 -var = v[2] -- ./compiler/lua54.can:204 -val = { -- ./compiler/lua54.can:205 -["tag"] = "Index", -- ./compiler/lua54.can:205 -{ -- ./compiler/lua54.can:205 -["tag"] = "Id", -- ./compiler/lua54.can:205 -list["id"] -- ./compiler/lua54.can:205 -}, -- ./compiler/lua54.can:205 -v[1] -- ./compiler/lua54.can:205 -} -- ./compiler/lua54.can:205 -else -- ./compiler/lua54.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 -end -- ./compiler/lua54.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["rightOp"], -- ./compiler/lua54.can:210 -var, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["leftOp"], -- ./compiler/lua54.can:210 -val, -- ./compiler/lua54.can:210 -var -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 -val = { -- ./compiler/lua54.can:212 -["tag"] = "Op", -- ./compiler/lua54.can:212 -destructured["rightOp"], -- ./compiler/lua54.can:212 -var, -- ./compiler/lua54.can:212 -val -- ./compiler/lua54.can:212 -} -- ./compiler/lua54.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 -val = { -- ./compiler/lua54.can:214 -["tag"] = "Op", -- ./compiler/lua54.can:214 -destructured["leftOp"], -- ./compiler/lua54.can:214 -val, -- ./compiler/lua54.can:214 -var -- ./compiler/lua54.can:214 -} -- ./compiler/lua54.can:214 -end -- ./compiler/lua54.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -if # vars > 0 then -- ./compiler/lua54.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 -if newlineAfter then -- ./compiler/lua54.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 -else -- ./compiler/lua54.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -else -- ./compiler/lua54.can:225 -return "" -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -tags = setmetatable({ -- ./compiler/lua54.can:233 -["Block"] = function(t) -- ./compiler/lua54.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 -hasPush = false -- ./compiler/lua54.can:239 -end -- ./compiler/lua54.can:239 -local r = push("scope", {}) -- ./compiler/lua54.can:241 -if hasPush then -- ./compiler/lua54.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 -end -- ./compiler/lua54.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 -end -- ./compiler/lua54.can:246 -if t[# t] then -- ./compiler/lua54.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +local CONTINUE_START = function() -- ./compiler/lua54.can:194 +return "do" .. indent() -- ./compiler/lua54.can:195 +end -- ./compiler/lua54.can:195 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 +end -- ./compiler/lua54.can:198 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 +local vars = {} -- ./compiler/lua54.can:201 +local values = {} -- ./compiler/lua54.can:202 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 +for _, v in ipairs(list) do -- ./compiler/lua54.can:204 +local var, val -- ./compiler/lua54.can:205 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 +var = v -- ./compiler/lua54.can:207 +val = { -- ./compiler/lua54.can:208 +["tag"] = "Index", -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "Id", -- ./compiler/lua54.can:208 +list["id"] -- ./compiler/lua54.can:208 +}, -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "String", -- ./compiler/lua54.can:208 +v[1] -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 +var = v[2] -- ./compiler/lua54.can:210 +val = { -- ./compiler/lua54.can:211 +["tag"] = "Index", -- ./compiler/lua54.can:211 +{ -- ./compiler/lua54.can:211 +["tag"] = "Id", -- ./compiler/lua54.can:211 +list["id"] -- ./compiler/lua54.can:211 +}, -- ./compiler/lua54.can:211 +v[1] -- ./compiler/lua54.can:211 +} -- ./compiler/lua54.can:211 +else -- ./compiler/lua54.can:211 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 +end -- ./compiler/lua54.can:213 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 +val = { -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["rightOp"], -- ./compiler/lua54.can:216 +var, -- ./compiler/lua54.can:216 +{ -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["leftOp"], -- ./compiler/lua54.can:216 +val, -- ./compiler/lua54.can:216 +var -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +val = { -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["rightOp"], -- ./compiler/lua54.can:218 +var, -- ./compiler/lua54.can:218 +val -- ./compiler/lua54.can:218 +} -- ./compiler/lua54.can:218 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +val = { -- ./compiler/lua54.can:220 +["tag"] = "Op", -- ./compiler/lua54.can:220 +destructured["leftOp"], -- ./compiler/lua54.can:220 +val, -- ./compiler/lua54.can:220 +var -- ./compiler/lua54.can:220 +} -- ./compiler/lua54.can:220 +end -- ./compiler/lua54.can:220 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +if # vars > 0 then -- ./compiler/lua54.can:226 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 +if newlineAfter then -- ./compiler/lua54.can:228 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 +else -- ./compiler/lua54.can:229 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 +end -- ./compiler/lua54.can:231 +else -- ./compiler/lua54.can:231 +return "" -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +tags = setmetatable({ -- ./compiler/lua54.can:239 +["Block"] = function(t) -- ./compiler/lua54.can:241 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 +hasPush = false -- ./compiler/lua54.can:245 +end -- ./compiler/lua54.can:245 +local r = push("scope", {}) -- ./compiler/lua54.can:247 +if hasPush then -- ./compiler/lua54.can:248 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 end -- ./compiler/lua54.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 end -- ./compiler/lua54.can:252 -return r .. pop("scope") -- ./compiler/lua54.can:254 -end, -- ./compiler/lua54.can:254 -["Do"] = function(t) -- ./compiler/lua54.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 -end, -- ./compiler/lua54.can:261 -["Set"] = function(t) -- ./compiler/lua54.can:264 -local expr = t[# t] -- ./compiler/lua54.can:266 -local vars, values = {}, {} -- ./compiler/lua54.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 -else -- ./compiler/lua54.can:272 -table["insert"](vars, n) -- ./compiler/lua54.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 -local r = "" -- ./compiler/lua54.can:280 -if # vars > 0 then -- ./compiler/lua54.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 -end -- ./compiler/lua54.can:282 -if # destructuringVars > 0 then -- ./compiler/lua54.can:284 -local destructured = {} -- ./compiler/lua54.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 -end -- ./compiler/lua54.can:287 -return r -- ./compiler/lua54.can:289 -elseif # t == 4 then -- ./compiler/lua54.can:290 -if t[3] == "=" then -- ./compiler/lua54.can:291 -local r = "" -- ./compiler/lua54.can:292 -if # vars > 0 then -- ./compiler/lua54.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 -t[2], -- ./compiler/lua54.can:294 -vars[1], -- ./compiler/lua54.can:294 -{ -- ./compiler/lua54.can:294 -["tag"] = "Paren", -- ./compiler/lua54.can:294 -values[1] -- ./compiler/lua54.can:294 -} -- ./compiler/lua54.can:294 -}, "Op")) -- ./compiler/lua54.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 -t[2], -- ./compiler/lua54.can:296 -vars[i], -- ./compiler/lua54.can:296 -{ -- ./compiler/lua54.can:296 -["tag"] = "Paren", -- ./compiler/lua54.can:296 -values[i] -- ./compiler/lua54.can:296 -} -- ./compiler/lua54.can:296 -}, "Op")) -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -if # destructuringVars > 0 then -- ./compiler/lua54.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +if t[# t] then -- ./compiler/lua54.can:254 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 +end -- ./compiler/lua54.can:255 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 +end -- ./compiler/lua54.can:258 +return r .. pop("scope") -- ./compiler/lua54.can:260 +end, -- ./compiler/lua54.can:260 +["Do"] = function(t) -- ./compiler/lua54.can:266 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 +end, -- ./compiler/lua54.can:267 +["Set"] = function(t) -- ./compiler/lua54.can:270 +local expr = t[# t] -- ./compiler/lua54.can:272 +local vars, values = {}, {} -- ./compiler/lua54.can:273 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 +else -- ./compiler/lua54.can:278 +table["insert"](vars, n) -- ./compiler/lua54.can:280 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 +local r = "" -- ./compiler/lua54.can:286 +if # vars > 0 then -- ./compiler/lua54.can:287 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 +end -- ./compiler/lua54.can:288 +if # destructuringVars > 0 then -- ./compiler/lua54.can:290 +local destructured = {} -- ./compiler/lua54.can:291 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 +end -- ./compiler/lua54.can:293 +return r -- ./compiler/lua54.can:295 +elseif # t == 4 then -- ./compiler/lua54.can:296 +if t[3] == "=" then -- ./compiler/lua54.can:297 +local r = "" -- ./compiler/lua54.can:298 +if # vars > 0 then -- ./compiler/lua54.can:299 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 +t[2], -- ./compiler/lua54.can:300 +vars[1], -- ./compiler/lua54.can:300 +{ -- ./compiler/lua54.can:300 +["tag"] = "Paren", -- ./compiler/lua54.can:300 +values[1] -- ./compiler/lua54.can:300 +} -- ./compiler/lua54.can:300 +}, "Op")) -- ./compiler/lua54.can:300 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +t[2], -- ./compiler/lua54.can:302 +vars[i], -- ./compiler/lua54.can:302 +{ -- ./compiler/lua54.can:302 +["tag"] = "Paren", -- ./compiler/lua54.can:302 +values[i] -- ./compiler/lua54.can:302 +} -- ./compiler/lua54.can:302 +}, "Op")) -- ./compiler/lua54.can:302 end -- ./compiler/lua54.can:302 -return r -- ./compiler/lua54.can:304 -else -- ./compiler/lua54.can:304 -local r = "" -- ./compiler/lua54.can:306 -if # vars > 0 then -- ./compiler/lua54.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 -t[3], -- ./compiler/lua54.can:308 -{ -- ./compiler/lua54.can:308 -["tag"] = "Paren", -- ./compiler/lua54.can:308 -values[1] -- ./compiler/lua54.can:308 -}, -- ./compiler/lua54.can:308 -vars[1] -- ./compiler/lua54.can:308 -}, "Op")) -- ./compiler/lua54.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 -t[3], -- ./compiler/lua54.can:310 -{ -- ./compiler/lua54.can:310 -["tag"] = "Paren", -- ./compiler/lua54.can:310 -values[i] -- ./compiler/lua54.can:310 -}, -- ./compiler/lua54.can:310 -vars[i] -- ./compiler/lua54.can:310 -}, "Op")) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -if # destructuringVars > 0 then -- ./compiler/lua54.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:302 +if # destructuringVars > 0 then -- ./compiler/lua54.can:305 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 +end -- ./compiler/lua54.can:308 +return r -- ./compiler/lua54.can:310 +else -- ./compiler/lua54.can:310 +local r = "" -- ./compiler/lua54.can:312 +if # vars > 0 then -- ./compiler/lua54.can:313 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 +t[3], -- ./compiler/lua54.can:314 +{ -- ./compiler/lua54.can:314 +["tag"] = "Paren", -- ./compiler/lua54.can:314 +values[1] -- ./compiler/lua54.can:314 +}, -- ./compiler/lua54.can:314 +vars[1] -- ./compiler/lua54.can:314 +}, "Op")) -- ./compiler/lua54.can:314 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +t[3], -- ./compiler/lua54.can:316 +{ -- ./compiler/lua54.can:316 +["tag"] = "Paren", -- ./compiler/lua54.can:316 +values[i] -- ./compiler/lua54.can:316 +}, -- ./compiler/lua54.can:316 +vars[i] -- ./compiler/lua54.can:316 +}, "Op")) -- ./compiler/lua54.can:316 end -- ./compiler/lua54.can:316 -return r -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -else -- ./compiler/lua54.can:318 -local r = "" -- ./compiler/lua54.can:321 -if # vars > 0 then -- ./compiler/lua54.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 -t[2], -- ./compiler/lua54.can:323 -vars[1], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Op", -- ./compiler/lua54.can:323 -t[4], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Paren", -- ./compiler/lua54.can:323 -values[1] -- ./compiler/lua54.can:323 -}, -- ./compiler/lua54.can:323 -vars[1] -- ./compiler/lua54.can:323 -} -- ./compiler/lua54.can:323 -}, "Op")) -- ./compiler/lua54.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 -t[2], -- ./compiler/lua54.can:325 -vars[i], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Op", -- ./compiler/lua54.can:325 -t[4], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Paren", -- ./compiler/lua54.can:325 -values[i] -- ./compiler/lua54.can:325 -}, -- ./compiler/lua54.can:325 -vars[i] -- ./compiler/lua54.can:325 -} -- ./compiler/lua54.can:325 -}, "Op")) -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -if # destructuringVars > 0 then -- ./compiler/lua54.can:328 -local destructured = { -- ./compiler/lua54.can:329 -["rightOp"] = t[2], -- ./compiler/lua54.can:329 -["leftOp"] = t[4] -- ./compiler/lua54.can:329 +end -- ./compiler/lua54.can:316 +if # destructuringVars > 0 then -- ./compiler/lua54.can:319 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 +end -- ./compiler/lua54.can:322 +return r -- ./compiler/lua54.can:324 +end -- ./compiler/lua54.can:324 +else -- ./compiler/lua54.can:324 +local r = "" -- ./compiler/lua54.can:327 +if # vars > 0 then -- ./compiler/lua54.can:328 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 +t[2], -- ./compiler/lua54.can:329 +vars[1], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Op", -- ./compiler/lua54.can:329 +t[4], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Paren", -- ./compiler/lua54.can:329 +values[1] -- ./compiler/lua54.can:329 +}, -- ./compiler/lua54.can:329 +vars[1] -- ./compiler/lua54.can:329 } -- ./compiler/lua54.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:329 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +t[2], -- ./compiler/lua54.can:331 +vars[i], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Op", -- ./compiler/lua54.can:331 +t[4], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Paren", -- ./compiler/lua54.can:331 +values[i] -- ./compiler/lua54.can:331 +}, -- ./compiler/lua54.can:331 +vars[i] -- ./compiler/lua54.can:331 +} -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:331 end -- ./compiler/lua54.can:331 -return r -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end, -- ./compiler/lua54.can:333 -["While"] = function(t) -- ./compiler/lua54.can:337 -local r = "" -- ./compiler/lua54.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 -if # lets > 0 then -- ./compiler/lua54.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 -if # lets > 0 then -- ./compiler/lua54.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 -end -- ./compiler/lua54.can:349 -if hasContinue then -- ./compiler/lua54.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 -if hasContinue then -- ./compiler/lua54.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 -end -- ./compiler/lua54.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 -if # lets > 0 then -- ./compiler/lua54.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 -end -- ./compiler/lua54.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 -end -- ./compiler/lua54.can:363 -return r -- ./compiler/lua54.can:365 -end, -- ./compiler/lua54.can:365 -["Repeat"] = function(t) -- ./compiler/lua54.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 -local r = "repeat" .. indent() -- ./compiler/lua54.can:370 -if hasContinue then -- ./compiler/lua54.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 -end -- ./compiler/lua54.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 -if hasContinue then -- ./compiler/lua54.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 -end -- ./compiler/lua54.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 -return r -- ./compiler/lua54.can:379 -end, -- ./compiler/lua54.can:379 -["If"] = function(t) -- ./compiler/lua54.can:382 -local r = "" -- ./compiler/lua54.can:383 -local toClose = 0 -- ./compiler/lua54.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 -if # lets > 0 then -- ./compiler/lua54.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 -toClose = toClose + (1) -- ./compiler/lua54.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 -if # lets > 0 then -- ./compiler/lua54.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 -toClose = toClose + (1) -- ./compiler/lua54.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 -end -- ./compiler/lua54.can:400 -else -- ./compiler/lua54.can:400 -r = r .. ("else") -- ./compiler/lua54.can:403 -end -- ./compiler/lua54.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 -end -- ./compiler/lua54.can:405 -if # t % 2 == 1 then -- ./compiler/lua54.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -r = r .. ("end") -- ./compiler/lua54.can:410 -for i = 1, toClose do -- ./compiler/lua54.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 -end -- ./compiler/lua54.can:412 -return r -- ./compiler/lua54.can:414 -end, -- ./compiler/lua54.can:414 -["Fornum"] = function(t) -- ./compiler/lua54.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 -if # t == 5 then -- ./compiler/lua54.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 -if hasContinue then -- ./compiler/lua54.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 -end -- ./compiler/lua54.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 -if hasContinue then -- ./compiler/lua54.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 -end -- ./compiler/lua54.can:427 -return r .. unindent() .. "end" -- ./compiler/lua54.can:429 -else -- ./compiler/lua54.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 -if hasContinue then -- ./compiler/lua54.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 -end -- ./compiler/lua54.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 -if hasContinue then -- ./compiler/lua54.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 -end -- ./compiler/lua54.can:438 -return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:331 +if # destructuringVars > 0 then -- ./compiler/lua54.can:334 +local destructured = { -- ./compiler/lua54.can:335 +["rightOp"] = t[2], -- ./compiler/lua54.can:335 +["leftOp"] = t[4] -- ./compiler/lua54.can:335 +} -- ./compiler/lua54.can:335 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 +end -- ./compiler/lua54.can:337 +return r -- ./compiler/lua54.can:339 +end -- ./compiler/lua54.can:339 +end, -- ./compiler/lua54.can:339 +["While"] = function(t) -- ./compiler/lua54.can:343 +local r = "" -- ./compiler/lua54.can:344 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 +if # lets > 0 then -- ./compiler/lua54.can:347 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 +if # lets > 0 then -- ./compiler/lua54.can:354 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 +end -- ./compiler/lua54.can:355 +if hasContinue then -- ./compiler/lua54.can:357 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 +end -- ./compiler/lua54.can:358 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 +if hasContinue then -- ./compiler/lua54.can:361 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 +end -- ./compiler/lua54.can:362 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 +if # lets > 0 then -- ./compiler/lua54.can:365 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 +end -- ./compiler/lua54.can:367 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +end -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:371 +end, -- ./compiler/lua54.can:371 +["Repeat"] = function(t) -- ./compiler/lua54.can:374 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 +local r = "repeat" .. indent() -- ./compiler/lua54.can:376 +if hasContinue then -- ./compiler/lua54.can:377 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 +end -- ./compiler/lua54.can:378 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 +if hasContinue then -- ./compiler/lua54.can:381 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 +end -- ./compiler/lua54.can:382 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 +return r -- ./compiler/lua54.can:385 +end, -- ./compiler/lua54.can:385 +["If"] = function(t) -- ./compiler/lua54.can:388 +local r = "" -- ./compiler/lua54.can:389 +local toClose = 0 -- ./compiler/lua54.can:390 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 +if # lets > 0 then -- ./compiler/lua54.can:392 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 +toClose = toClose + (1) -- ./compiler/lua54.can:394 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 +if # lets > 0 then -- ./compiler/lua54.can:402 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 +toClose = toClose + (1) -- ./compiler/lua54.can:404 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 +end -- ./compiler/lua54.can:406 +else -- ./compiler/lua54.can:406 +r = r .. ("else") -- ./compiler/lua54.can:409 +end -- ./compiler/lua54.can:409 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +end -- ./compiler/lua54.can:411 +if # t % 2 == 1 then -- ./compiler/lua54.can:413 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 +end -- ./compiler/lua54.can:414 +r = r .. ("end") -- ./compiler/lua54.can:416 +for i = 1, toClose do -- ./compiler/lua54.can:417 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 +end -- ./compiler/lua54.can:418 +return r -- ./compiler/lua54.can:420 +end, -- ./compiler/lua54.can:420 +["Fornum"] = function(t) -- ./compiler/lua54.can:423 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 +if # t == 5 then -- ./compiler/lua54.can:425 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 +if hasContinue then -- ./compiler/lua54.can:428 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 +end -- ./compiler/lua54.can:429 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 +if hasContinue then -- ./compiler/lua54.can:432 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 +end -- ./compiler/lua54.can:433 +return r .. unindent() .. "end" -- ./compiler/lua54.can:435 +else -- ./compiler/lua54.can:435 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 +if hasContinue then -- ./compiler/lua54.can:439 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 end -- ./compiler/lua54.can:440 -end, -- ./compiler/lua54.can:440 -["Forin"] = function(t) -- ./compiler/lua54.can:444 -local destructured = {} -- ./compiler/lua54.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 -if hasContinue then -- ./compiler/lua54.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 -end -- ./compiler/lua54.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 -if hasContinue then -- ./compiler/lua54.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 -end -- ./compiler/lua54.can:453 -return r .. unindent() .. "end" -- ./compiler/lua54.can:455 -end, -- ./compiler/lua54.can:455 -["Local"] = function(t) -- ./compiler/lua54.can:458 -local destructured = {} -- ./compiler/lua54.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 -if t[2][1] then -- ./compiler/lua54.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 -end -- ./compiler/lua54.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 -end, -- ./compiler/lua54.can:464 -["Let"] = function(t) -- ./compiler/lua54.can:467 -local destructured = {} -- ./compiler/lua54.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 -local r = "local " .. nameList -- ./compiler/lua54.can:470 -if t[2][1] then -- ./compiler/lua54.can:471 -if all(t[2], { -- ./compiler/lua54.can:472 -"Nil", -- ./compiler/lua54.can:472 -"Dots", -- ./compiler/lua54.can:472 -"Boolean", -- ./compiler/lua54.can:472 -"Number", -- ./compiler/lua54.can:472 -"String" -- ./compiler/lua54.can:472 -}) then -- ./compiler/lua54.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 -else -- ./compiler/lua54.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 -end, -- ./compiler/lua54.can:478 -["Localrec"] = function(t) -- ./compiler/lua54.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 -end, -- ./compiler/lua54.can:482 -["Goto"] = function(t) -- ./compiler/lua54.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Label"] = function(t) -- ./compiler/lua54.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Return"] = function(t) -- ./compiler/lua54.can:493 -local push = peek("push") -- ./compiler/lua54.can:494 -if push then -- ./compiler/lua54.can:495 -local r = "" -- ./compiler/lua54.can:496 -for _, val in ipairs(t) do -- ./compiler/lua54.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 -end -- ./compiler/lua54.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 -else -- ./compiler/lua54.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 -end -- ./compiler/lua54.can:502 -end, -- ./compiler/lua54.can:502 -["Push"] = function(t) -- ./compiler/lua54.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 -r = "" -- ./compiler/lua54.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -if t[# t] then -- ./compiler/lua54.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 -else -- ./compiler/lua54.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 +if hasContinue then -- ./compiler/lua54.can:443 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 +end -- ./compiler/lua54.can:444 +return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +end -- ./compiler/lua54.can:446 +end, -- ./compiler/lua54.can:446 +["Forin"] = function(t) -- ./compiler/lua54.can:450 +local destructured = {} -- ./compiler/lua54.can:451 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 +if hasContinue then -- ./compiler/lua54.can:454 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 +end -- ./compiler/lua54.can:455 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 +if hasContinue then -- ./compiler/lua54.can:458 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 +end -- ./compiler/lua54.can:459 +return r .. unindent() .. "end" -- ./compiler/lua54.can:461 +end, -- ./compiler/lua54.can:461 +["Local"] = function(t) -- ./compiler/lua54.can:464 +local destructured = {} -- ./compiler/lua54.can:465 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 +if t[2][1] then -- ./compiler/lua54.can:467 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 +end -- ./compiler/lua54.can:468 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 +end, -- ./compiler/lua54.can:470 +["Let"] = function(t) -- ./compiler/lua54.can:473 +local destructured = {} -- ./compiler/lua54.can:474 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 +local r = "local " .. nameList -- ./compiler/lua54.can:476 +if t[2][1] then -- ./compiler/lua54.can:477 +if all(t[2], { -- ./compiler/lua54.can:478 +"Nil", -- ./compiler/lua54.can:478 +"Dots", -- ./compiler/lua54.can:478 +"Boolean", -- ./compiler/lua54.can:478 +"Number", -- ./compiler/lua54.can:478 +"String" -- ./compiler/lua54.can:478 +}) then -- ./compiler/lua54.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 +else -- ./compiler/lua54.can:479 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 +end, -- ./compiler/lua54.can:484 +["Localrec"] = function(t) -- ./compiler/lua54.can:487 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 +end, -- ./compiler/lua54.can:488 +["Goto"] = function(t) -- ./compiler/lua54.can:491 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 +end, -- ./compiler/lua54.can:492 +["Label"] = function(t) -- ./compiler/lua54.can:495 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 +end, -- ./compiler/lua54.can:496 +["Return"] = function(t) -- ./compiler/lua54.can:499 +local push = peek("push") -- ./compiler/lua54.can:500 +if push then -- ./compiler/lua54.can:501 +local r = "" -- ./compiler/lua54.can:502 +for _, val in ipairs(t) do -- ./compiler/lua54.can:503 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 +end -- ./compiler/lua54.can:504 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 +else -- ./compiler/lua54.can:506 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 +end -- ./compiler/lua54.can:508 +end, -- ./compiler/lua54.can:508 +["Push"] = function(t) -- ./compiler/lua54.can:512 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 +r = "" -- ./compiler/lua54.can:514 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 end -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -return r -- ./compiler/lua54.can:519 -end, -- ./compiler/lua54.can:519 -["Break"] = function() -- ./compiler/lua54.can:522 -return "break" -- ./compiler/lua54.can:523 -end, -- ./compiler/lua54.can:523 -["Continue"] = function() -- ./compiler/lua54.can:526 -return "goto " .. var("continue") -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Nil"] = function() -- ./compiler/lua54.can:534 -return "nil" -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Dots"] = function() -- ./compiler/lua54.can:538 -return "..." -- ./compiler/lua54.can:539 -end, -- ./compiler/lua54.can:539 -["Boolean"] = function(t) -- ./compiler/lua54.can:542 -return tostring(t[1]) -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Number"] = function(t) -- ./compiler/lua54.can:546 -return tostring(t[1]) -- ./compiler/lua54.can:547 -end, -- ./compiler/lua54.can:547 -["String"] = function(t) -- ./compiler/lua54.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 -end, -- ./compiler/lua54.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 -local r = "(" -- ./compiler/lua54.can:555 -local decl = {} -- ./compiler/lua54.can:556 -if t[1][1] then -- ./compiler/lua54.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 -r = r .. (id) -- ./compiler/lua54.can:563 -else -- ./compiler/lua54.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 -end -- ./compiler/lua54.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 -r = r .. (", " .. id) -- ./compiler/lua54.can:573 -else -- ./compiler/lua54.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 -r = r .. (d .. newline()) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 -end -- ./compiler/lua54.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 -if hasPush then -- ./compiler/lua54.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 -else -- ./compiler/lua54.can:588 -push("push", false) -- ./compiler/lua54.can:590 -end -- ./compiler/lua54.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 -end -- ./compiler/lua54.can:594 -pop("push") -- ./compiler/lua54.can:596 -return r .. unindent() .. "end" -- ./compiler/lua54.can:597 -end, -- ./compiler/lua54.can:597 -["Function"] = function(t) -- ./compiler/lua54.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 -end, -- ./compiler/lua54.can:600 -["Pair"] = function(t) -- ./compiler/lua54.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 -end, -- ./compiler/lua54.can:604 -["Table"] = function(t) -- ./compiler/lua54.can:606 -if # t == 0 then -- ./compiler/lua54.can:607 -return "{}" -- ./compiler/lua54.can:608 -elseif # t == 1 then -- ./compiler/lua54.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 -else -- ./compiler/lua54.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 -end -- ./compiler/lua54.can:612 -end, -- ./compiler/lua54.can:612 -["TableCompr"] = function(t) -- ./compiler/lua54.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 -end, -- ./compiler/lua54.can:617 -["Op"] = function(t) -- ./compiler/lua54.can:620 -local r -- ./compiler/lua54.can:621 -if # t == 2 then -- ./compiler/lua54.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +if t[# t] then -- ./compiler/lua54.can:518 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 +else -- ./compiler/lua54.can:520 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +return r -- ./compiler/lua54.can:525 +end, -- ./compiler/lua54.can:525 +["Break"] = function() -- ./compiler/lua54.can:528 +return "break" -- ./compiler/lua54.can:529 +end, -- ./compiler/lua54.can:529 +["Continue"] = function() -- ./compiler/lua54.can:532 +return "goto " .. var("continue") -- ./compiler/lua54.can:533 +end, -- ./compiler/lua54.can:533 +["Nil"] = function() -- ./compiler/lua54.can:540 +return "nil" -- ./compiler/lua54.can:541 +end, -- ./compiler/lua54.can:541 +["Dots"] = function() -- ./compiler/lua54.can:544 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 +return r -- ./compiler/lua54.can:550 +else -- ./compiler/lua54.can:550 +return "..." -- ./compiler/lua54.can:552 +end -- ./compiler/lua54.can:552 +end, -- ./compiler/lua54.can:552 +["Boolean"] = function(t) -- ./compiler/lua54.can:556 +return tostring(t[1]) -- ./compiler/lua54.can:557 +end, -- ./compiler/lua54.can:557 +["Number"] = function(t) -- ./compiler/lua54.can:560 +return tostring(t[1]) -- ./compiler/lua54.can:561 +end, -- ./compiler/lua54.can:561 +["String"] = function(t) -- ./compiler/lua54.can:564 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 +end, -- ./compiler/lua54.can:565 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 +local r = "(" -- ./compiler/lua54.can:569 +local decl = {} -- ./compiler/lua54.can:570 +if t[1][1] then -- ./compiler/lua54.can:571 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 +r = r .. (id) -- ./compiler/lua54.can:577 +else -- ./compiler/lua54.can:577 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 +end -- ./compiler/lua54.can:579 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 +r = r .. (", " .. id) -- ./compiler/lua54.can:587 +else -- ./compiler/lua54.can:587 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 +r = r .. (d .. newline()) -- ./compiler/lua54.can:595 +end -- ./compiler/lua54.can:595 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 +end -- ./compiler/lua54.can:598 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 +if hasPush then -- ./compiler/lua54.can:601 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 +else -- ./compiler/lua54.can:602 +push("push", false) -- ./compiler/lua54.can:604 +end -- ./compiler/lua54.can:604 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 +end -- ./compiler/lua54.can:608 +pop("push") -- ./compiler/lua54.can:610 +return r .. unindent() .. "end" -- ./compiler/lua54.can:611 +end, -- ./compiler/lua54.can:611 +["Function"] = function(t) -- ./compiler/lua54.can:613 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 +end, -- ./compiler/lua54.can:614 +["Pair"] = function(t) -- ./compiler/lua54.can:617 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 +end, -- ./compiler/lua54.can:618 +["Table"] = function(t) -- ./compiler/lua54.can:620 +if # t == 0 then -- ./compiler/lua54.can:621 +return "{}" -- ./compiler/lua54.can:622 +elseif # t == 1 then -- ./compiler/lua54.can:623 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 else -- ./compiler/lua54.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 end -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 -else -- ./compiler/lua54.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -return r -- ./compiler/lua54.can:635 -end, -- ./compiler/lua54.can:635 -["Paren"] = function(t) -- ./compiler/lua54.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 -end, -- ./compiler/lua54.can:639 -["MethodStub"] = function(t) -- ./compiler/lua54.can:642 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 -end, -- ./compiler/lua54.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 -end, -- ./compiler/lua54.can:658 -["LetExpr"] = function(t) -- ./compiler/lua54.can:665 -return lua(t[1][1]) -- ./compiler/lua54.can:666 -end, -- ./compiler/lua54.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 -local r = "(function()" .. indent() -- ./compiler/lua54.can:672 -if hasPush then -- ./compiler/lua54.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 -else -- ./compiler/lua54.can:674 -push("push", false) -- ./compiler/lua54.can:676 -end -- ./compiler/lua54.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 -if hasPush then -- ./compiler/lua54.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 -end -- ./compiler/lua54.can:680 -pop("push") -- ./compiler/lua54.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 -return r -- ./compiler/lua54.can:684 -end, -- ./compiler/lua54.can:684 -["DoExpr"] = function(t) -- ./compiler/lua54.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 -end -- ./compiler/lua54.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 -end, -- ./compiler/lua54.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 -end, -- ./compiler/lua54.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 -end, -- ./compiler/lua54.can:699 -["IfExpr"] = function(t) -- ./compiler/lua54.can:702 -for i = 2, # t do -- ./compiler/lua54.can:703 -local block = t[i] -- ./compiler/lua54.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:626 +["TableCompr"] = function(t) -- ./compiler/lua54.can:630 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 +end, -- ./compiler/lua54.can:631 +["Op"] = function(t) -- ./compiler/lua54.can:634 +local r -- ./compiler/lua54.can:635 +if # t == 2 then -- ./compiler/lua54.can:636 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 +else -- ./compiler/lua54.can:638 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 +end -- ./compiler/lua54.can:640 +else -- ./compiler/lua54.can:640 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 +else -- ./compiler/lua54.can:644 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +return r -- ./compiler/lua54.can:649 +end, -- ./compiler/lua54.can:649 +["Paren"] = function(t) -- ./compiler/lua54.can:652 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 +end, -- ./compiler/lua54.can:653 +["MethodStub"] = function(t) -- ./compiler/lua54.can:656 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 +end, -- ./compiler/lua54.can:662 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 +end, -- ./compiler/lua54.can:672 +["LetExpr"] = function(t) -- ./compiler/lua54.can:679 +return lua(t[1][1]) -- ./compiler/lua54.can:680 +end, -- ./compiler/lua54.can:680 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 +local r = "(function()" .. indent() -- ./compiler/lua54.can:686 +if hasPush then -- ./compiler/lua54.can:687 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 +else -- ./compiler/lua54.can:688 +push("push", false) -- ./compiler/lua54.can:690 +end -- ./compiler/lua54.can:690 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 +if hasPush then -- ./compiler/lua54.can:693 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 +end -- ./compiler/lua54.can:694 +pop("push") -- ./compiler/lua54.can:696 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 +return r -- ./compiler/lua54.can:698 +end, -- ./compiler/lua54.can:698 +["DoExpr"] = function(t) -- ./compiler/lua54.can:701 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 +end -- ./compiler/lua54.can:703 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 +end, -- ./compiler/lua54.can:705 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 end, -- ./compiler/lua54.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 end, -- ./compiler/lua54.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 -end, -- ./compiler/lua54.can:717 -["Call"] = function(t) -- ./compiler/lua54.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 -else -- ./compiler/lua54.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 -end -- ./compiler/lua54.can:730 -else -- ./compiler/lua54.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 -end -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["SafeCall"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 -else -- ./compiler/lua54.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 -end -- ./compiler/lua54.can:741 -end, -- ./compiler/lua54.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 -if start == nil then start = 1 end -- ./compiler/lua54.can:746 -local r -- ./compiler/lua54.can:747 -if t[start] then -- ./compiler/lua54.can:748 -r = lua(t[start]) -- ./compiler/lua54.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 -end -- ./compiler/lua54.can:751 +["IfExpr"] = function(t) -- ./compiler/lua54.can:716 +for i = 2, # t do -- ./compiler/lua54.can:717 +local block = t[i] -- ./compiler/lua54.can:718 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 +end, -- ./compiler/lua54.can:723 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 +end, -- ./compiler/lua54.can:727 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 +end, -- ./compiler/lua54.can:731 +["Call"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 +local replacement = macro["replacement"] -- ./compiler/lua54.can:742 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 +macroargs["..."] = (function() -- ./compiler/lua54.can:746 +local self = {} -- ./compiler/lua54.can:746 +for j = i + 1, # t do -- ./compiler/lua54.can:746 +self[#self+1] = t[j] -- ./compiler/lua54.can:746 +end -- ./compiler/lua54.can:746 +return self -- ./compiler/lua54.can:746 +end)() -- ./compiler/lua54.can:746 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 +if t[i + 1] == nil then -- ./compiler/lua54.can:748 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 +end -- ./compiler/lua54.can:749 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 else -- ./compiler/lua54.can:751 -r = "" -- ./compiler/lua54.can:754 -end -- ./compiler/lua54.can:754 -return r -- ./compiler/lua54.can:756 -end, -- ./compiler/lua54.can:756 -["Id"] = function(t) -- ./compiler/lua54.can:759 -return t[1] -- ./compiler/lua54.can:760 -end, -- ./compiler/lua54.can:760 -["AttributeId"] = function(t) -- ./compiler/lua54.can:763 -if t[2] then -- ./compiler/lua54.can:764 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 -else -- ./compiler/lua54.can:765 -return t[1] -- ./compiler/lua54.can:767 -end -- ./compiler/lua54.can:767 -end, -- ./compiler/lua54.can:767 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 -if t["id"] then -- ./compiler/lua54.can:772 -return t["id"] -- ./compiler/lua54.can:773 -else -- ./compiler/lua54.can:773 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 -for j = 1, # t, 1 do -- ./compiler/lua54.can:777 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 -end -- ./compiler/lua54.can:778 -table["insert"](d, vars) -- ./compiler/lua54.can:780 -t["id"] = vars["id"] -- ./compiler/lua54.can:781 -return vars["id"] -- ./compiler/lua54.can:782 -end -- ./compiler/lua54.can:782 -end, -- ./compiler/lua54.can:782 -["Index"] = function(t) -- ./compiler/lua54.can:786 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 -else -- ./compiler/lua54.can:788 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +push("macroargs", macroargs) -- ./compiler/lua54.can:756 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 +local r = lua(replacement) -- ./compiler/lua54.can:758 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 +pop("macroargs") -- ./compiler/lua54.can:760 +return r -- ./compiler/lua54.can:761 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 +else -- ./compiler/lua54.can:764 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 +end -- ./compiler/lua54.can:766 +else -- ./compiler/lua54.can:766 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +end -- ./compiler/lua54.can:769 +end, -- ./compiler/lua54.can:769 +["SafeCall"] = function(t) -- ./compiler/lua54.can:773 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +else -- ./compiler/lua54.can:775 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +end -- ./compiler/lua54.can:777 +end, -- ./compiler/lua54.can:777 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 +if start == nil then start = 1 end -- ./compiler/lua54.can:782 +local r -- ./compiler/lua54.can:783 +if t[start] then -- ./compiler/lua54.can:784 +r = lua(t[start]) -- ./compiler/lua54.can:785 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 +end -- ./compiler/lua54.can:787 +else -- ./compiler/lua54.can:787 +r = "" -- ./compiler/lua54.can:790 end -- ./compiler/lua54.can:790 -end, -- ./compiler/lua54.can:790 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 -local l = {} -- ./compiler/lua54.can:796 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 -table["insert"](l, 1, t) -- ./compiler/lua54.can:798 -t = t[1] -- ./compiler/lua54.can:799 -end -- ./compiler/lua54.can:799 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 -for _, e in ipairs(l) do -- ./compiler/lua54.can:802 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 -else -- ./compiler/lua54.can:805 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +return r -- ./compiler/lua54.can:792 +end, -- ./compiler/lua54.can:792 +["Id"] = function(t) -- ./compiler/lua54.can:795 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 +local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:802 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 +local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 +return r -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 -return r -- ./compiler/lua54.can:811 -else -- ./compiler/lua54.can:811 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 -end -- ./compiler/lua54.can:813 -end, -- ./compiler/lua54.can:813 -["_opid"] = { -- ./compiler/lua54.can:818 -["add"] = "+", -- ./compiler/lua54.can:819 -["sub"] = "-", -- ./compiler/lua54.can:819 -["mul"] = "*", -- ./compiler/lua54.can:819 -["div"] = "/", -- ./compiler/lua54.can:819 -["idiv"] = "//", -- ./compiler/lua54.can:820 -["mod"] = "%", -- ./compiler/lua54.can:820 -["pow"] = "^", -- ./compiler/lua54.can:820 -["concat"] = "..", -- ./compiler/lua54.can:820 -["band"] = "&", -- ./compiler/lua54.can:821 -["bor"] = "|", -- ./compiler/lua54.can:821 -["bxor"] = "~", -- ./compiler/lua54.can:821 -["shl"] = "<<", -- ./compiler/lua54.can:821 -["shr"] = ">>", -- ./compiler/lua54.can:821 -["eq"] = "==", -- ./compiler/lua54.can:822 -["ne"] = "~=", -- ./compiler/lua54.can:822 -["lt"] = "<", -- ./compiler/lua54.can:822 -["gt"] = ">", -- ./compiler/lua54.can:822 -["le"] = "<=", -- ./compiler/lua54.can:822 -["ge"] = ">=", -- ./compiler/lua54.can:822 -["and"] = "and", -- ./compiler/lua54.can:823 -["or"] = "or", -- ./compiler/lua54.can:823 -["unm"] = "-", -- ./compiler/lua54.can:823 -["len"] = "#", -- ./compiler/lua54.can:823 -["bnot"] = "~", -- ./compiler/lua54.can:823 -["not"] = "not" -- ./compiler/lua54.can:823 -} -- ./compiler/lua54.can:823 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 -end }) -- ./compiler/lua54.can:827 +return t[1] -- ./compiler/lua54.can:810 +end, -- ./compiler/lua54.can:810 +["AttributeId"] = function(t) -- ./compiler/lua54.can:813 +if t[2] then -- ./compiler/lua54.can:814 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 +else -- ./compiler/lua54.can:815 +return t[1] -- ./compiler/lua54.can:817 +end -- ./compiler/lua54.can:817 +end, -- ./compiler/lua54.can:817 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 +if t["id"] then -- ./compiler/lua54.can:822 +return t["id"] -- ./compiler/lua54.can:823 +else -- ./compiler/lua54.can:823 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 +for j = 1, # t, 1 do -- ./compiler/lua54.can:827 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 +end -- ./compiler/lua54.can:828 +table["insert"](d, vars) -- ./compiler/lua54.can:830 +t["id"] = vars["id"] -- ./compiler/lua54.can:831 +return vars["id"] -- ./compiler/lua54.can:832 +end -- ./compiler/lua54.can:832 +end, -- ./compiler/lua54.can:832 +["Index"] = function(t) -- ./compiler/lua54.can:836 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 +else -- ./compiler/lua54.can:838 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 +end -- ./compiler/lua54.can:840 +end, -- ./compiler/lua54.can:840 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 +local l = {} -- ./compiler/lua54.can:846 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 +table["insert"](l, 1, t) -- ./compiler/lua54.can:848 +t = t[1] -- ./compiler/lua54.can:849 +end -- ./compiler/lua54.can:849 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 +for _, e in ipairs(l) do -- ./compiler/lua54.can:852 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 +else -- ./compiler/lua54.can:855 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 +return r -- ./compiler/lua54.can:861 +else -- ./compiler/lua54.can:861 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 +end -- ./compiler/lua54.can:863 +end, -- ./compiler/lua54.can:863 +["_opid"] = { -- ./compiler/lua54.can:868 +["add"] = "+", -- ./compiler/lua54.can:869 +["sub"] = "-", -- ./compiler/lua54.can:869 +["mul"] = "*", -- ./compiler/lua54.can:869 +["div"] = "/", -- ./compiler/lua54.can:869 +["idiv"] = "//", -- ./compiler/lua54.can:870 +["mod"] = "%", -- ./compiler/lua54.can:870 +["pow"] = "^", -- ./compiler/lua54.can:870 +["concat"] = "..", -- ./compiler/lua54.can:870 +["band"] = "&", -- ./compiler/lua54.can:871 +["bor"] = "|", -- ./compiler/lua54.can:871 +["bxor"] = "~", -- ./compiler/lua54.can:871 +["shl"] = "<<", -- ./compiler/lua54.can:871 +["shr"] = ">>", -- ./compiler/lua54.can:871 +["eq"] = "==", -- ./compiler/lua54.can:872 +["ne"] = "~=", -- ./compiler/lua54.can:872 +["lt"] = "<", -- ./compiler/lua54.can:872 +["gt"] = ">", -- ./compiler/lua54.can:872 +["le"] = "<=", -- ./compiler/lua54.can:872 +["ge"] = ">=", -- ./compiler/lua54.can:872 +["and"] = "and", -- ./compiler/lua54.can:873 +["or"] = "or", -- ./compiler/lua54.can:873 +["unm"] = "-", -- ./compiler/lua54.can:873 +["len"] = "#", -- ./compiler/lua54.can:873 +["bnot"] = "~", -- ./compiler/lua54.can:873 +["not"] = "not" -- ./compiler/lua54.can:873 +} -- ./compiler/lua54.can:873 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 +end }) -- ./compiler/lua54.can:877 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -2755,11 +2948,11 @@ end -- ./compiler/lua52.can:23 tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 end -- ./compiler/lua52.can:26 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 -return requireStr .. code -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 +return requireStr .. code -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +local lua54 = _() or lua54 -- ./compiler/lua54.can:889 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -2771,861 +2964,921 @@ local function _() -- ./compiler/lua52.can:43 local function _() -- ./compiler/lua52.can:45 local function _() -- ./compiler/lua52.can:47 local function _() -- ./compiler/lua52.can:49 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 -return function(code, ast, options) -- ./compiler/lua54.can:3 -local lastInputPos = 1 -- ./compiler/lua54.can:5 -local prevLinePos = 1 -- ./compiler/lua54.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 -local lastLine = 1 -- ./compiler/lua54.can:8 -local indentLevel = 0 -- ./compiler/lua54.can:11 -local function newline() -- ./compiler/lua54.can:13 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 -if options["mapLines"] then -- ./compiler/lua54.can:15 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local util = require("candran.util") -- ./compiler/lua54.can:1 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 +return function(code, ast, options, macros) -- ./compiler/lua54.can:5 +if macros == nil then macros = { -- ./compiler/lua54.can:5 +["functions"] = {}, -- ./compiler/lua54.can:5 +["variables"] = {} -- ./compiler/lua54.can:5 +} end -- ./compiler/lua54.can:5 +local lastInputPos = 1 -- ./compiler/lua54.can:7 +local prevLinePos = 1 -- ./compiler/lua54.can:8 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 +local lastLine = 1 -- ./compiler/lua54.can:10 +local indentLevel = 0 -- ./compiler/lua54.can:13 +local function newline() -- ./compiler/lua54.can:15 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 +if options["mapLines"] then -- ./compiler/lua54.can:17 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:17 -if source and line then -- ./compiler/lua54.can:19 -lastSource = source -- ./compiler/lua54.can:20 -lastLine = tonumber(line) -- ./compiler/lua54.can:21 -else -- ./compiler/lua54.can:21 +") -- ./compiler/lua54.can:19 +if source and line then -- ./compiler/lua54.can:21 +lastSource = source -- ./compiler/lua54.can:22 +lastLine = tonumber(line) -- ./compiler/lua54.can:23 +else -- ./compiler/lua54.can:23 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:23 -lastLine = lastLine + (1) -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -prevLinePos = lastInputPos -- ./compiler/lua54.can:28 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 -end -- ./compiler/lua54.can:30 -return r -- ./compiler/lua54.can:32 +") do -- ./compiler/lua54.can:25 +lastLine = lastLine + (1) -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +prevLinePos = lastInputPos -- ./compiler/lua54.can:30 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 end -- ./compiler/lua54.can:32 -local function indent() -- ./compiler/lua54.can:35 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 -return newline() -- ./compiler/lua54.can:37 -end -- ./compiler/lua54.can:37 -local function unindent() -- ./compiler/lua54.can:40 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 -return newline() -- ./compiler/lua54.can:42 -end -- ./compiler/lua54.can:42 -local states = { -- ./compiler/lua54.can:47 -["push"] = {}, -- ./compiler/lua54.can:48 -["destructuring"] = {}, -- ./compiler/lua54.can:49 -["scope"] = {} -- ./compiler/lua54.can:50 -} -- ./compiler/lua54.can:50 -local function push(name, state) -- ./compiler/lua54.can:53 -table["insert"](states[name], state) -- ./compiler/lua54.can:54 -return "" -- ./compiler/lua54.can:55 -end -- ./compiler/lua54.can:55 -local function pop(name) -- ./compiler/lua54.can:58 -table["remove"](states[name]) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function set(name, state) -- ./compiler/lua54.can:63 -states[name][# states[name]] = state -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function peek(name) -- ./compiler/lua54.can:68 -return states[name][# states[name]] -- ./compiler/lua54.can:69 -end -- ./compiler/lua54.can:69 -local function var(name) -- ./compiler/lua54.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 -end -- ./compiler/lua54.can:75 -local function tmp() -- ./compiler/lua54.can:79 -local scope = peek("scope") -- ./compiler/lua54.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 -table["insert"](scope, var) -- ./compiler/lua54.can:82 -return var -- ./compiler/lua54.can:83 -end -- ./compiler/lua54.can:83 -local required = {} -- ./compiler/lua54.can:87 -local requireStr = "" -- ./compiler/lua54.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 -if not required[req] then -- ./compiler/lua54.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 -required[req] = true -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -local loop = { -- ./compiler/lua54.can:99 -"While", -- ./compiler/lua54.can:99 -"Repeat", -- ./compiler/lua54.can:99 -"Fornum", -- ./compiler/lua54.can:99 -"Forin", -- ./compiler/lua54.can:99 -"WhileExpr", -- ./compiler/lua54.can:99 -"RepeatExpr", -- ./compiler/lua54.can:99 -"FornumExpr", -- ./compiler/lua54.can:99 -"ForinExpr" -- ./compiler/lua54.can:99 -} -- ./compiler/lua54.can:99 -local func = { -- ./compiler/lua54.can:100 -"Function", -- ./compiler/lua54.can:100 -"TableCompr", -- ./compiler/lua54.can:100 -"DoExpr", -- ./compiler/lua54.can:100 -"WhileExpr", -- ./compiler/lua54.can:100 -"RepeatExpr", -- ./compiler/lua54.can:100 -"IfExpr", -- ./compiler/lua54.can:100 -"FornumExpr", -- ./compiler/lua54.can:100 -"ForinExpr" -- ./compiler/lua54.can:100 -} -- ./compiler/lua54.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 -local tagsCheck = {} -- ./compiler/lua54.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 -tagsCheck[tag] = true -- ./compiler/lua54.can:107 -end -- ./compiler/lua54.can:107 -local nofollowCheck = {} -- ./compiler/lua54.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 -nofollowCheck[tag] = true -- ./compiler/lua54.can:111 -end -- ./compiler/lua54.can:111 -for _, node in ipairs(list) do -- ./compiler/lua54.can:113 -if type(node) == "table" then -- ./compiler/lua54.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 -return node -- ./compiler/lua54.can:116 -end -- ./compiler/lua54.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 -if r then -- ./compiler/lua54.can:120 -return r -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -return nil -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 -local tagsCheck = {} -- ./compiler/lua54.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 -tagsCheck[tag] = true -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local nofollowCheck = {} -- ./compiler/lua54.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 -nofollowCheck[tag] = true -- ./compiler/lua54.can:136 -end -- ./compiler/lua54.can:136 -local found = {} -- ./compiler/lua54.can:138 -for _, node in ipairs(list) do -- ./compiler/lua54.can:139 -if type(node) == "table" then -- ./compiler/lua54.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 -table["insert"](found, n) -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 -table["insert"](found, node) -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -return found -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -local function all(list, tags) -- ./compiler/lua54.can:155 -for _, node in ipairs(list) do -- ./compiler/lua54.can:156 -local ok = false -- ./compiler/lua54.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 -if node["tag"] == tag then -- ./compiler/lua54.can:159 -ok = true -- ./compiler/lua54.can:160 -break -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -if not ok then -- ./compiler/lua54.can:164 -return false -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -return true -- ./compiler/lua54.can:168 -end -- ./compiler/lua54.can:168 -local tags -- ./compiler/lua54.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 -end -- ./compiler/lua54.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 -end -- ./compiler/lua54.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local CONTINUE_START = function() -- ./compiler/lua54.can:188 -return "do" .. indent() -- ./compiler/lua54.can:189 +return r -- ./compiler/lua54.can:34 +end -- ./compiler/lua54.can:34 +local function indent() -- ./compiler/lua54.can:37 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 +return newline() -- ./compiler/lua54.can:39 +end -- ./compiler/lua54.can:39 +local function unindent() -- ./compiler/lua54.can:42 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 +return newline() -- ./compiler/lua54.can:44 +end -- ./compiler/lua54.can:44 +local states = { -- ./compiler/lua54.can:49 +["push"] = {}, -- ./compiler/lua54.can:50 +["destructuring"] = {}, -- ./compiler/lua54.can:51 +["scope"] = {}, -- ./compiler/lua54.can:52 +["macroargs"] = {} -- ./compiler/lua54.can:53 +} -- ./compiler/lua54.can:53 +local function push(name, state) -- ./compiler/lua54.can:56 +table["insert"](states[name], state) -- ./compiler/lua54.can:57 +return "" -- ./compiler/lua54.can:58 +end -- ./compiler/lua54.can:58 +local function pop(name) -- ./compiler/lua54.can:61 +table["remove"](states[name]) -- ./compiler/lua54.can:62 +return "" -- ./compiler/lua54.can:63 +end -- ./compiler/lua54.can:63 +local function set(name, state) -- ./compiler/lua54.can:66 +states[name][# states[name]] = state -- ./compiler/lua54.can:67 +return "" -- ./compiler/lua54.can:68 +end -- ./compiler/lua54.can:68 +local function peek(name) -- ./compiler/lua54.can:71 +return states[name][# states[name]] -- ./compiler/lua54.can:72 +end -- ./compiler/lua54.can:72 +local function var(name) -- ./compiler/lua54.can:77 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 +end -- ./compiler/lua54.can:78 +local function tmp() -- ./compiler/lua54.can:82 +local scope = peek("scope") -- ./compiler/lua54.can:83 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 +table["insert"](scope, var) -- ./compiler/lua54.can:85 +return var -- ./compiler/lua54.can:86 +end -- ./compiler/lua54.can:86 +local nomacro = { -- ./compiler/lua54.can:90 +["variables"] = {}, -- ./compiler/lua54.can:90 +["functions"] = {} -- ./compiler/lua54.can:90 +} -- ./compiler/lua54.can:90 +local required = {} -- ./compiler/lua54.can:93 +local requireStr = "" -- ./compiler/lua54.can:94 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 +if not required[req] then -- ./compiler/lua54.can:98 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 +required[req] = true -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +local loop = { -- ./compiler/lua54.can:105 +"While", -- ./compiler/lua54.can:105 +"Repeat", -- ./compiler/lua54.can:105 +"Fornum", -- ./compiler/lua54.can:105 +"Forin", -- ./compiler/lua54.can:105 +"WhileExpr", -- ./compiler/lua54.can:105 +"RepeatExpr", -- ./compiler/lua54.can:105 +"FornumExpr", -- ./compiler/lua54.can:105 +"ForinExpr" -- ./compiler/lua54.can:105 +} -- ./compiler/lua54.can:105 +local func = { -- ./compiler/lua54.can:106 +"Function", -- ./compiler/lua54.can:106 +"TableCompr", -- ./compiler/lua54.can:106 +"DoExpr", -- ./compiler/lua54.can:106 +"WhileExpr", -- ./compiler/lua54.can:106 +"RepeatExpr", -- ./compiler/lua54.can:106 +"IfExpr", -- ./compiler/lua54.can:106 +"FornumExpr", -- ./compiler/lua54.can:106 +"ForinExpr" -- ./compiler/lua54.can:106 +} -- ./compiler/lua54.can:106 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 +local tagsCheck = {} -- ./compiler/lua54.can:111 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 +tagsCheck[tag] = true -- ./compiler/lua54.can:113 +end -- ./compiler/lua54.can:113 +local nofollowCheck = {} -- ./compiler/lua54.can:115 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 +nofollowCheck[tag] = true -- ./compiler/lua54.can:117 +end -- ./compiler/lua54.can:117 +for _, node in ipairs(list) do -- ./compiler/lua54.can:119 +if type(node) == "table" then -- ./compiler/lua54.can:120 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 +return node -- ./compiler/lua54.can:122 +end -- ./compiler/lua54.can:122 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 +if r then -- ./compiler/lua54.can:126 +return r -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +return nil -- ./compiler/lua54.can:130 +end -- ./compiler/lua54.can:130 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 +local tagsCheck = {} -- ./compiler/lua54.can:136 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 +tagsCheck[tag] = true -- ./compiler/lua54.can:138 +end -- ./compiler/lua54.can:138 +local nofollowCheck = {} -- ./compiler/lua54.can:140 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 +nofollowCheck[tag] = true -- ./compiler/lua54.can:142 +end -- ./compiler/lua54.can:142 +local found = {} -- ./compiler/lua54.can:144 +for _, node in ipairs(list) do -- ./compiler/lua54.can:145 +if type(node) == "table" then -- ./compiler/lua54.can:146 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 +table["insert"](found, n) -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 +table["insert"](found, node) -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +return found -- ./compiler/lua54.can:157 +end -- ./compiler/lua54.can:157 +local function all(list, tags) -- ./compiler/lua54.can:161 +for _, node in ipairs(list) do -- ./compiler/lua54.can:162 +local ok = false -- ./compiler/lua54.can:163 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 +if node["tag"] == tag then -- ./compiler/lua54.can:165 +ok = true -- ./compiler/lua54.can:166 +break -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +if not ok then -- ./compiler/lua54.can:170 +return false -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +return true -- ./compiler/lua54.can:174 +end -- ./compiler/lua54.can:174 +local tags -- ./compiler/lua54.can:178 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 +end -- ./compiler/lua54.can:182 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +end -- ./compiler/lua54.can:184 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 end -- ./compiler/lua54.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 end -- ./compiler/lua54.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 -local vars = {} -- ./compiler/lua54.can:195 -local values = {} -- ./compiler/lua54.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 -for _, v in ipairs(list) do -- ./compiler/lua54.can:198 -local var, val -- ./compiler/lua54.can:199 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 -var = v -- ./compiler/lua54.can:201 -val = { -- ./compiler/lua54.can:202 -["tag"] = "Index", -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "Id", -- ./compiler/lua54.can:202 -list["id"] -- ./compiler/lua54.can:202 -}, -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "String", -- ./compiler/lua54.can:202 -v[1] -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 -var = v[2] -- ./compiler/lua54.can:204 -val = { -- ./compiler/lua54.can:205 -["tag"] = "Index", -- ./compiler/lua54.can:205 -{ -- ./compiler/lua54.can:205 -["tag"] = "Id", -- ./compiler/lua54.can:205 -list["id"] -- ./compiler/lua54.can:205 -}, -- ./compiler/lua54.can:205 -v[1] -- ./compiler/lua54.can:205 -} -- ./compiler/lua54.can:205 -else -- ./compiler/lua54.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 -end -- ./compiler/lua54.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["rightOp"], -- ./compiler/lua54.can:210 -var, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["leftOp"], -- ./compiler/lua54.can:210 -val, -- ./compiler/lua54.can:210 -var -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 -val = { -- ./compiler/lua54.can:212 -["tag"] = "Op", -- ./compiler/lua54.can:212 -destructured["rightOp"], -- ./compiler/lua54.can:212 -var, -- ./compiler/lua54.can:212 -val -- ./compiler/lua54.can:212 -} -- ./compiler/lua54.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 -val = { -- ./compiler/lua54.can:214 -["tag"] = "Op", -- ./compiler/lua54.can:214 -destructured["leftOp"], -- ./compiler/lua54.can:214 -val, -- ./compiler/lua54.can:214 -var -- ./compiler/lua54.can:214 -} -- ./compiler/lua54.can:214 -end -- ./compiler/lua54.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -if # vars > 0 then -- ./compiler/lua54.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 -if newlineAfter then -- ./compiler/lua54.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 -else -- ./compiler/lua54.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -else -- ./compiler/lua54.can:225 -return "" -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -tags = setmetatable({ -- ./compiler/lua54.can:233 -["Block"] = function(t) -- ./compiler/lua54.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 -hasPush = false -- ./compiler/lua54.can:239 -end -- ./compiler/lua54.can:239 -local r = push("scope", {}) -- ./compiler/lua54.can:241 -if hasPush then -- ./compiler/lua54.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 -end -- ./compiler/lua54.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 -end -- ./compiler/lua54.can:246 -if t[# t] then -- ./compiler/lua54.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +local CONTINUE_START = function() -- ./compiler/lua54.can:194 +return "do" .. indent() -- ./compiler/lua54.can:195 +end -- ./compiler/lua54.can:195 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 +end -- ./compiler/lua54.can:198 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 +local vars = {} -- ./compiler/lua54.can:201 +local values = {} -- ./compiler/lua54.can:202 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 +for _, v in ipairs(list) do -- ./compiler/lua54.can:204 +local var, val -- ./compiler/lua54.can:205 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 +var = v -- ./compiler/lua54.can:207 +val = { -- ./compiler/lua54.can:208 +["tag"] = "Index", -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "Id", -- ./compiler/lua54.can:208 +list["id"] -- ./compiler/lua54.can:208 +}, -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "String", -- ./compiler/lua54.can:208 +v[1] -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 +var = v[2] -- ./compiler/lua54.can:210 +val = { -- ./compiler/lua54.can:211 +["tag"] = "Index", -- ./compiler/lua54.can:211 +{ -- ./compiler/lua54.can:211 +["tag"] = "Id", -- ./compiler/lua54.can:211 +list["id"] -- ./compiler/lua54.can:211 +}, -- ./compiler/lua54.can:211 +v[1] -- ./compiler/lua54.can:211 +} -- ./compiler/lua54.can:211 +else -- ./compiler/lua54.can:211 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 +end -- ./compiler/lua54.can:213 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 +val = { -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["rightOp"], -- ./compiler/lua54.can:216 +var, -- ./compiler/lua54.can:216 +{ -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["leftOp"], -- ./compiler/lua54.can:216 +val, -- ./compiler/lua54.can:216 +var -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +val = { -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["rightOp"], -- ./compiler/lua54.can:218 +var, -- ./compiler/lua54.can:218 +val -- ./compiler/lua54.can:218 +} -- ./compiler/lua54.can:218 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +val = { -- ./compiler/lua54.can:220 +["tag"] = "Op", -- ./compiler/lua54.can:220 +destructured["leftOp"], -- ./compiler/lua54.can:220 +val, -- ./compiler/lua54.can:220 +var -- ./compiler/lua54.can:220 +} -- ./compiler/lua54.can:220 +end -- ./compiler/lua54.can:220 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +if # vars > 0 then -- ./compiler/lua54.can:226 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 +if newlineAfter then -- ./compiler/lua54.can:228 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 +else -- ./compiler/lua54.can:229 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 +end -- ./compiler/lua54.can:231 +else -- ./compiler/lua54.can:231 +return "" -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +tags = setmetatable({ -- ./compiler/lua54.can:239 +["Block"] = function(t) -- ./compiler/lua54.can:241 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 +hasPush = false -- ./compiler/lua54.can:245 +end -- ./compiler/lua54.can:245 +local r = push("scope", {}) -- ./compiler/lua54.can:247 +if hasPush then -- ./compiler/lua54.can:248 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 end -- ./compiler/lua54.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 end -- ./compiler/lua54.can:252 -return r .. pop("scope") -- ./compiler/lua54.can:254 -end, -- ./compiler/lua54.can:254 -["Do"] = function(t) -- ./compiler/lua54.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 -end, -- ./compiler/lua54.can:261 -["Set"] = function(t) -- ./compiler/lua54.can:264 -local expr = t[# t] -- ./compiler/lua54.can:266 -local vars, values = {}, {} -- ./compiler/lua54.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 -else -- ./compiler/lua54.can:272 -table["insert"](vars, n) -- ./compiler/lua54.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 -local r = "" -- ./compiler/lua54.can:280 -if # vars > 0 then -- ./compiler/lua54.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 -end -- ./compiler/lua54.can:282 -if # destructuringVars > 0 then -- ./compiler/lua54.can:284 -local destructured = {} -- ./compiler/lua54.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 -end -- ./compiler/lua54.can:287 -return r -- ./compiler/lua54.can:289 -elseif # t == 4 then -- ./compiler/lua54.can:290 -if t[3] == "=" then -- ./compiler/lua54.can:291 -local r = "" -- ./compiler/lua54.can:292 -if # vars > 0 then -- ./compiler/lua54.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 -t[2], -- ./compiler/lua54.can:294 -vars[1], -- ./compiler/lua54.can:294 -{ -- ./compiler/lua54.can:294 -["tag"] = "Paren", -- ./compiler/lua54.can:294 -values[1] -- ./compiler/lua54.can:294 -} -- ./compiler/lua54.can:294 -}, "Op")) -- ./compiler/lua54.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 -t[2], -- ./compiler/lua54.can:296 -vars[i], -- ./compiler/lua54.can:296 -{ -- ./compiler/lua54.can:296 -["tag"] = "Paren", -- ./compiler/lua54.can:296 -values[i] -- ./compiler/lua54.can:296 -} -- ./compiler/lua54.can:296 -}, "Op")) -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -if # destructuringVars > 0 then -- ./compiler/lua54.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +if t[# t] then -- ./compiler/lua54.can:254 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 +end -- ./compiler/lua54.can:255 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 +end -- ./compiler/lua54.can:258 +return r .. pop("scope") -- ./compiler/lua54.can:260 +end, -- ./compiler/lua54.can:260 +["Do"] = function(t) -- ./compiler/lua54.can:266 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 +end, -- ./compiler/lua54.can:267 +["Set"] = function(t) -- ./compiler/lua54.can:270 +local expr = t[# t] -- ./compiler/lua54.can:272 +local vars, values = {}, {} -- ./compiler/lua54.can:273 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 +else -- ./compiler/lua54.can:278 +table["insert"](vars, n) -- ./compiler/lua54.can:280 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 +local r = "" -- ./compiler/lua54.can:286 +if # vars > 0 then -- ./compiler/lua54.can:287 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 +end -- ./compiler/lua54.can:288 +if # destructuringVars > 0 then -- ./compiler/lua54.can:290 +local destructured = {} -- ./compiler/lua54.can:291 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 +end -- ./compiler/lua54.can:293 +return r -- ./compiler/lua54.can:295 +elseif # t == 4 then -- ./compiler/lua54.can:296 +if t[3] == "=" then -- ./compiler/lua54.can:297 +local r = "" -- ./compiler/lua54.can:298 +if # vars > 0 then -- ./compiler/lua54.can:299 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 +t[2], -- ./compiler/lua54.can:300 +vars[1], -- ./compiler/lua54.can:300 +{ -- ./compiler/lua54.can:300 +["tag"] = "Paren", -- ./compiler/lua54.can:300 +values[1] -- ./compiler/lua54.can:300 +} -- ./compiler/lua54.can:300 +}, "Op")) -- ./compiler/lua54.can:300 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +t[2], -- ./compiler/lua54.can:302 +vars[i], -- ./compiler/lua54.can:302 +{ -- ./compiler/lua54.can:302 +["tag"] = "Paren", -- ./compiler/lua54.can:302 +values[i] -- ./compiler/lua54.can:302 +} -- ./compiler/lua54.can:302 +}, "Op")) -- ./compiler/lua54.can:302 end -- ./compiler/lua54.can:302 -return r -- ./compiler/lua54.can:304 -else -- ./compiler/lua54.can:304 -local r = "" -- ./compiler/lua54.can:306 -if # vars > 0 then -- ./compiler/lua54.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 -t[3], -- ./compiler/lua54.can:308 -{ -- ./compiler/lua54.can:308 -["tag"] = "Paren", -- ./compiler/lua54.can:308 -values[1] -- ./compiler/lua54.can:308 -}, -- ./compiler/lua54.can:308 -vars[1] -- ./compiler/lua54.can:308 -}, "Op")) -- ./compiler/lua54.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 -t[3], -- ./compiler/lua54.can:310 -{ -- ./compiler/lua54.can:310 -["tag"] = "Paren", -- ./compiler/lua54.can:310 -values[i] -- ./compiler/lua54.can:310 -}, -- ./compiler/lua54.can:310 -vars[i] -- ./compiler/lua54.can:310 -}, "Op")) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -if # destructuringVars > 0 then -- ./compiler/lua54.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:302 +if # destructuringVars > 0 then -- ./compiler/lua54.can:305 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 +end -- ./compiler/lua54.can:308 +return r -- ./compiler/lua54.can:310 +else -- ./compiler/lua54.can:310 +local r = "" -- ./compiler/lua54.can:312 +if # vars > 0 then -- ./compiler/lua54.can:313 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 +t[3], -- ./compiler/lua54.can:314 +{ -- ./compiler/lua54.can:314 +["tag"] = "Paren", -- ./compiler/lua54.can:314 +values[1] -- ./compiler/lua54.can:314 +}, -- ./compiler/lua54.can:314 +vars[1] -- ./compiler/lua54.can:314 +}, "Op")) -- ./compiler/lua54.can:314 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +t[3], -- ./compiler/lua54.can:316 +{ -- ./compiler/lua54.can:316 +["tag"] = "Paren", -- ./compiler/lua54.can:316 +values[i] -- ./compiler/lua54.can:316 +}, -- ./compiler/lua54.can:316 +vars[i] -- ./compiler/lua54.can:316 +}, "Op")) -- ./compiler/lua54.can:316 end -- ./compiler/lua54.can:316 -return r -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -else -- ./compiler/lua54.can:318 -local r = "" -- ./compiler/lua54.can:321 -if # vars > 0 then -- ./compiler/lua54.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 -t[2], -- ./compiler/lua54.can:323 -vars[1], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Op", -- ./compiler/lua54.can:323 -t[4], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Paren", -- ./compiler/lua54.can:323 -values[1] -- ./compiler/lua54.can:323 -}, -- ./compiler/lua54.can:323 -vars[1] -- ./compiler/lua54.can:323 -} -- ./compiler/lua54.can:323 -}, "Op")) -- ./compiler/lua54.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 -t[2], -- ./compiler/lua54.can:325 -vars[i], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Op", -- ./compiler/lua54.can:325 -t[4], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Paren", -- ./compiler/lua54.can:325 -values[i] -- ./compiler/lua54.can:325 -}, -- ./compiler/lua54.can:325 -vars[i] -- ./compiler/lua54.can:325 -} -- ./compiler/lua54.can:325 -}, "Op")) -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -if # destructuringVars > 0 then -- ./compiler/lua54.can:328 -local destructured = { -- ./compiler/lua54.can:329 -["rightOp"] = t[2], -- ./compiler/lua54.can:329 -["leftOp"] = t[4] -- ./compiler/lua54.can:329 +end -- ./compiler/lua54.can:316 +if # destructuringVars > 0 then -- ./compiler/lua54.can:319 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 +end -- ./compiler/lua54.can:322 +return r -- ./compiler/lua54.can:324 +end -- ./compiler/lua54.can:324 +else -- ./compiler/lua54.can:324 +local r = "" -- ./compiler/lua54.can:327 +if # vars > 0 then -- ./compiler/lua54.can:328 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 +t[2], -- ./compiler/lua54.can:329 +vars[1], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Op", -- ./compiler/lua54.can:329 +t[4], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Paren", -- ./compiler/lua54.can:329 +values[1] -- ./compiler/lua54.can:329 +}, -- ./compiler/lua54.can:329 +vars[1] -- ./compiler/lua54.can:329 } -- ./compiler/lua54.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:329 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +t[2], -- ./compiler/lua54.can:331 +vars[i], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Op", -- ./compiler/lua54.can:331 +t[4], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Paren", -- ./compiler/lua54.can:331 +values[i] -- ./compiler/lua54.can:331 +}, -- ./compiler/lua54.can:331 +vars[i] -- ./compiler/lua54.can:331 +} -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:331 end -- ./compiler/lua54.can:331 -return r -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end, -- ./compiler/lua54.can:333 -["While"] = function(t) -- ./compiler/lua54.can:337 -local r = "" -- ./compiler/lua54.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 -if # lets > 0 then -- ./compiler/lua54.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 -if # lets > 0 then -- ./compiler/lua54.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 -end -- ./compiler/lua54.can:349 -if hasContinue then -- ./compiler/lua54.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 -if hasContinue then -- ./compiler/lua54.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 -end -- ./compiler/lua54.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 -if # lets > 0 then -- ./compiler/lua54.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 -end -- ./compiler/lua54.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 -end -- ./compiler/lua54.can:363 -return r -- ./compiler/lua54.can:365 -end, -- ./compiler/lua54.can:365 -["Repeat"] = function(t) -- ./compiler/lua54.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 -local r = "repeat" .. indent() -- ./compiler/lua54.can:370 -if hasContinue then -- ./compiler/lua54.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 -end -- ./compiler/lua54.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 -if hasContinue then -- ./compiler/lua54.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 -end -- ./compiler/lua54.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 -return r -- ./compiler/lua54.can:379 -end, -- ./compiler/lua54.can:379 -["If"] = function(t) -- ./compiler/lua54.can:382 -local r = "" -- ./compiler/lua54.can:383 -local toClose = 0 -- ./compiler/lua54.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 -if # lets > 0 then -- ./compiler/lua54.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 -toClose = toClose + (1) -- ./compiler/lua54.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 -if # lets > 0 then -- ./compiler/lua54.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 -toClose = toClose + (1) -- ./compiler/lua54.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 -end -- ./compiler/lua54.can:400 -else -- ./compiler/lua54.can:400 -r = r .. ("else") -- ./compiler/lua54.can:403 -end -- ./compiler/lua54.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 -end -- ./compiler/lua54.can:405 -if # t % 2 == 1 then -- ./compiler/lua54.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -r = r .. ("end") -- ./compiler/lua54.can:410 -for i = 1, toClose do -- ./compiler/lua54.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 -end -- ./compiler/lua54.can:412 -return r -- ./compiler/lua54.can:414 -end, -- ./compiler/lua54.can:414 -["Fornum"] = function(t) -- ./compiler/lua54.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 -if # t == 5 then -- ./compiler/lua54.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 -if hasContinue then -- ./compiler/lua54.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 -end -- ./compiler/lua54.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 -if hasContinue then -- ./compiler/lua54.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 -end -- ./compiler/lua54.can:427 -return r .. unindent() .. "end" -- ./compiler/lua54.can:429 -else -- ./compiler/lua54.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 -if hasContinue then -- ./compiler/lua54.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 -end -- ./compiler/lua54.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 -if hasContinue then -- ./compiler/lua54.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 -end -- ./compiler/lua54.can:438 -return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:331 +if # destructuringVars > 0 then -- ./compiler/lua54.can:334 +local destructured = { -- ./compiler/lua54.can:335 +["rightOp"] = t[2], -- ./compiler/lua54.can:335 +["leftOp"] = t[4] -- ./compiler/lua54.can:335 +} -- ./compiler/lua54.can:335 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 +end -- ./compiler/lua54.can:337 +return r -- ./compiler/lua54.can:339 +end -- ./compiler/lua54.can:339 +end, -- ./compiler/lua54.can:339 +["While"] = function(t) -- ./compiler/lua54.can:343 +local r = "" -- ./compiler/lua54.can:344 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 +if # lets > 0 then -- ./compiler/lua54.can:347 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 +if # lets > 0 then -- ./compiler/lua54.can:354 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 +end -- ./compiler/lua54.can:355 +if hasContinue then -- ./compiler/lua54.can:357 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 +end -- ./compiler/lua54.can:358 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 +if hasContinue then -- ./compiler/lua54.can:361 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 +end -- ./compiler/lua54.can:362 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 +if # lets > 0 then -- ./compiler/lua54.can:365 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 +end -- ./compiler/lua54.can:367 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +end -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:371 +end, -- ./compiler/lua54.can:371 +["Repeat"] = function(t) -- ./compiler/lua54.can:374 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 +local r = "repeat" .. indent() -- ./compiler/lua54.can:376 +if hasContinue then -- ./compiler/lua54.can:377 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 +end -- ./compiler/lua54.can:378 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 +if hasContinue then -- ./compiler/lua54.can:381 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 +end -- ./compiler/lua54.can:382 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 +return r -- ./compiler/lua54.can:385 +end, -- ./compiler/lua54.can:385 +["If"] = function(t) -- ./compiler/lua54.can:388 +local r = "" -- ./compiler/lua54.can:389 +local toClose = 0 -- ./compiler/lua54.can:390 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 +if # lets > 0 then -- ./compiler/lua54.can:392 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 +toClose = toClose + (1) -- ./compiler/lua54.can:394 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 +if # lets > 0 then -- ./compiler/lua54.can:402 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 +toClose = toClose + (1) -- ./compiler/lua54.can:404 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 +end -- ./compiler/lua54.can:406 +else -- ./compiler/lua54.can:406 +r = r .. ("else") -- ./compiler/lua54.can:409 +end -- ./compiler/lua54.can:409 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +end -- ./compiler/lua54.can:411 +if # t % 2 == 1 then -- ./compiler/lua54.can:413 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 +end -- ./compiler/lua54.can:414 +r = r .. ("end") -- ./compiler/lua54.can:416 +for i = 1, toClose do -- ./compiler/lua54.can:417 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 +end -- ./compiler/lua54.can:418 +return r -- ./compiler/lua54.can:420 +end, -- ./compiler/lua54.can:420 +["Fornum"] = function(t) -- ./compiler/lua54.can:423 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 +if # t == 5 then -- ./compiler/lua54.can:425 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 +if hasContinue then -- ./compiler/lua54.can:428 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 +end -- ./compiler/lua54.can:429 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 +if hasContinue then -- ./compiler/lua54.can:432 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 +end -- ./compiler/lua54.can:433 +return r .. unindent() .. "end" -- ./compiler/lua54.can:435 +else -- ./compiler/lua54.can:435 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 +if hasContinue then -- ./compiler/lua54.can:439 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 end -- ./compiler/lua54.can:440 -end, -- ./compiler/lua54.can:440 -["Forin"] = function(t) -- ./compiler/lua54.can:444 -local destructured = {} -- ./compiler/lua54.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 -if hasContinue then -- ./compiler/lua54.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 -end -- ./compiler/lua54.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 -if hasContinue then -- ./compiler/lua54.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 -end -- ./compiler/lua54.can:453 -return r .. unindent() .. "end" -- ./compiler/lua54.can:455 -end, -- ./compiler/lua54.can:455 -["Local"] = function(t) -- ./compiler/lua54.can:458 -local destructured = {} -- ./compiler/lua54.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 -if t[2][1] then -- ./compiler/lua54.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 -end -- ./compiler/lua54.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 -end, -- ./compiler/lua54.can:464 -["Let"] = function(t) -- ./compiler/lua54.can:467 -local destructured = {} -- ./compiler/lua54.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 -local r = "local " .. nameList -- ./compiler/lua54.can:470 -if t[2][1] then -- ./compiler/lua54.can:471 -if all(t[2], { -- ./compiler/lua54.can:472 -"Nil", -- ./compiler/lua54.can:472 -"Dots", -- ./compiler/lua54.can:472 -"Boolean", -- ./compiler/lua54.can:472 -"Number", -- ./compiler/lua54.can:472 -"String" -- ./compiler/lua54.can:472 -}) then -- ./compiler/lua54.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 -else -- ./compiler/lua54.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 -end, -- ./compiler/lua54.can:478 -["Localrec"] = function(t) -- ./compiler/lua54.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 -end, -- ./compiler/lua54.can:482 -["Goto"] = function(t) -- ./compiler/lua54.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Label"] = function(t) -- ./compiler/lua54.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Return"] = function(t) -- ./compiler/lua54.can:493 -local push = peek("push") -- ./compiler/lua54.can:494 -if push then -- ./compiler/lua54.can:495 -local r = "" -- ./compiler/lua54.can:496 -for _, val in ipairs(t) do -- ./compiler/lua54.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 -end -- ./compiler/lua54.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 -else -- ./compiler/lua54.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 -end -- ./compiler/lua54.can:502 -end, -- ./compiler/lua54.can:502 -["Push"] = function(t) -- ./compiler/lua54.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 -r = "" -- ./compiler/lua54.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -if t[# t] then -- ./compiler/lua54.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 -else -- ./compiler/lua54.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 +if hasContinue then -- ./compiler/lua54.can:443 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 +end -- ./compiler/lua54.can:444 +return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +end -- ./compiler/lua54.can:446 +end, -- ./compiler/lua54.can:446 +["Forin"] = function(t) -- ./compiler/lua54.can:450 +local destructured = {} -- ./compiler/lua54.can:451 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 +if hasContinue then -- ./compiler/lua54.can:454 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 +end -- ./compiler/lua54.can:455 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 +if hasContinue then -- ./compiler/lua54.can:458 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 +end -- ./compiler/lua54.can:459 +return r .. unindent() .. "end" -- ./compiler/lua54.can:461 +end, -- ./compiler/lua54.can:461 +["Local"] = function(t) -- ./compiler/lua54.can:464 +local destructured = {} -- ./compiler/lua54.can:465 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 +if t[2][1] then -- ./compiler/lua54.can:467 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 +end -- ./compiler/lua54.can:468 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 +end, -- ./compiler/lua54.can:470 +["Let"] = function(t) -- ./compiler/lua54.can:473 +local destructured = {} -- ./compiler/lua54.can:474 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 +local r = "local " .. nameList -- ./compiler/lua54.can:476 +if t[2][1] then -- ./compiler/lua54.can:477 +if all(t[2], { -- ./compiler/lua54.can:478 +"Nil", -- ./compiler/lua54.can:478 +"Dots", -- ./compiler/lua54.can:478 +"Boolean", -- ./compiler/lua54.can:478 +"Number", -- ./compiler/lua54.can:478 +"String" -- ./compiler/lua54.can:478 +}) then -- ./compiler/lua54.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 +else -- ./compiler/lua54.can:479 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 +end, -- ./compiler/lua54.can:484 +["Localrec"] = function(t) -- ./compiler/lua54.can:487 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 +end, -- ./compiler/lua54.can:488 +["Goto"] = function(t) -- ./compiler/lua54.can:491 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 +end, -- ./compiler/lua54.can:492 +["Label"] = function(t) -- ./compiler/lua54.can:495 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 +end, -- ./compiler/lua54.can:496 +["Return"] = function(t) -- ./compiler/lua54.can:499 +local push = peek("push") -- ./compiler/lua54.can:500 +if push then -- ./compiler/lua54.can:501 +local r = "" -- ./compiler/lua54.can:502 +for _, val in ipairs(t) do -- ./compiler/lua54.can:503 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 +end -- ./compiler/lua54.can:504 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 +else -- ./compiler/lua54.can:506 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 +end -- ./compiler/lua54.can:508 +end, -- ./compiler/lua54.can:508 +["Push"] = function(t) -- ./compiler/lua54.can:512 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 +r = "" -- ./compiler/lua54.can:514 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 end -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -return r -- ./compiler/lua54.can:519 -end, -- ./compiler/lua54.can:519 -["Break"] = function() -- ./compiler/lua54.can:522 -return "break" -- ./compiler/lua54.can:523 -end, -- ./compiler/lua54.can:523 -["Continue"] = function() -- ./compiler/lua54.can:526 -return "goto " .. var("continue") -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Nil"] = function() -- ./compiler/lua54.can:534 -return "nil" -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Dots"] = function() -- ./compiler/lua54.can:538 -return "..." -- ./compiler/lua54.can:539 -end, -- ./compiler/lua54.can:539 -["Boolean"] = function(t) -- ./compiler/lua54.can:542 -return tostring(t[1]) -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Number"] = function(t) -- ./compiler/lua54.can:546 -return tostring(t[1]) -- ./compiler/lua54.can:547 -end, -- ./compiler/lua54.can:547 -["String"] = function(t) -- ./compiler/lua54.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 -end, -- ./compiler/lua54.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 -local r = "(" -- ./compiler/lua54.can:555 -local decl = {} -- ./compiler/lua54.can:556 -if t[1][1] then -- ./compiler/lua54.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 -r = r .. (id) -- ./compiler/lua54.can:563 -else -- ./compiler/lua54.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 -end -- ./compiler/lua54.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 -r = r .. (", " .. id) -- ./compiler/lua54.can:573 -else -- ./compiler/lua54.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 -r = r .. (d .. newline()) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 -end -- ./compiler/lua54.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 -if hasPush then -- ./compiler/lua54.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 -else -- ./compiler/lua54.can:588 -push("push", false) -- ./compiler/lua54.can:590 -end -- ./compiler/lua54.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 -end -- ./compiler/lua54.can:594 -pop("push") -- ./compiler/lua54.can:596 -return r .. unindent() .. "end" -- ./compiler/lua54.can:597 -end, -- ./compiler/lua54.can:597 -["Function"] = function(t) -- ./compiler/lua54.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 -end, -- ./compiler/lua54.can:600 -["Pair"] = function(t) -- ./compiler/lua54.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 -end, -- ./compiler/lua54.can:604 -["Table"] = function(t) -- ./compiler/lua54.can:606 -if # t == 0 then -- ./compiler/lua54.can:607 -return "{}" -- ./compiler/lua54.can:608 -elseif # t == 1 then -- ./compiler/lua54.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 -else -- ./compiler/lua54.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 -end -- ./compiler/lua54.can:612 -end, -- ./compiler/lua54.can:612 -["TableCompr"] = function(t) -- ./compiler/lua54.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 -end, -- ./compiler/lua54.can:617 -["Op"] = function(t) -- ./compiler/lua54.can:620 -local r -- ./compiler/lua54.can:621 -if # t == 2 then -- ./compiler/lua54.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +if t[# t] then -- ./compiler/lua54.can:518 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 +else -- ./compiler/lua54.can:520 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +return r -- ./compiler/lua54.can:525 +end, -- ./compiler/lua54.can:525 +["Break"] = function() -- ./compiler/lua54.can:528 +return "break" -- ./compiler/lua54.can:529 +end, -- ./compiler/lua54.can:529 +["Continue"] = function() -- ./compiler/lua54.can:532 +return "goto " .. var("continue") -- ./compiler/lua54.can:533 +end, -- ./compiler/lua54.can:533 +["Nil"] = function() -- ./compiler/lua54.can:540 +return "nil" -- ./compiler/lua54.can:541 +end, -- ./compiler/lua54.can:541 +["Dots"] = function() -- ./compiler/lua54.can:544 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 +return r -- ./compiler/lua54.can:550 +else -- ./compiler/lua54.can:550 +return "..." -- ./compiler/lua54.can:552 +end -- ./compiler/lua54.can:552 +end, -- ./compiler/lua54.can:552 +["Boolean"] = function(t) -- ./compiler/lua54.can:556 +return tostring(t[1]) -- ./compiler/lua54.can:557 +end, -- ./compiler/lua54.can:557 +["Number"] = function(t) -- ./compiler/lua54.can:560 +return tostring(t[1]) -- ./compiler/lua54.can:561 +end, -- ./compiler/lua54.can:561 +["String"] = function(t) -- ./compiler/lua54.can:564 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 +end, -- ./compiler/lua54.can:565 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 +local r = "(" -- ./compiler/lua54.can:569 +local decl = {} -- ./compiler/lua54.can:570 +if t[1][1] then -- ./compiler/lua54.can:571 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 +r = r .. (id) -- ./compiler/lua54.can:577 +else -- ./compiler/lua54.can:577 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 +end -- ./compiler/lua54.can:579 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 +r = r .. (", " .. id) -- ./compiler/lua54.can:587 +else -- ./compiler/lua54.can:587 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 +r = r .. (d .. newline()) -- ./compiler/lua54.can:595 +end -- ./compiler/lua54.can:595 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 +end -- ./compiler/lua54.can:598 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 +if hasPush then -- ./compiler/lua54.can:601 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 +else -- ./compiler/lua54.can:602 +push("push", false) -- ./compiler/lua54.can:604 +end -- ./compiler/lua54.can:604 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 +end -- ./compiler/lua54.can:608 +pop("push") -- ./compiler/lua54.can:610 +return r .. unindent() .. "end" -- ./compiler/lua54.can:611 +end, -- ./compiler/lua54.can:611 +["Function"] = function(t) -- ./compiler/lua54.can:613 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 +end, -- ./compiler/lua54.can:614 +["Pair"] = function(t) -- ./compiler/lua54.can:617 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 +end, -- ./compiler/lua54.can:618 +["Table"] = function(t) -- ./compiler/lua54.can:620 +if # t == 0 then -- ./compiler/lua54.can:621 +return "{}" -- ./compiler/lua54.can:622 +elseif # t == 1 then -- ./compiler/lua54.can:623 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 else -- ./compiler/lua54.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 end -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 -else -- ./compiler/lua54.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -return r -- ./compiler/lua54.can:635 -end, -- ./compiler/lua54.can:635 -["Paren"] = function(t) -- ./compiler/lua54.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 -end, -- ./compiler/lua54.can:639 -["MethodStub"] = function(t) -- ./compiler/lua54.can:642 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 -end, -- ./compiler/lua54.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 -end, -- ./compiler/lua54.can:658 -["LetExpr"] = function(t) -- ./compiler/lua54.can:665 -return lua(t[1][1]) -- ./compiler/lua54.can:666 -end, -- ./compiler/lua54.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 -local r = "(function()" .. indent() -- ./compiler/lua54.can:672 -if hasPush then -- ./compiler/lua54.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 -else -- ./compiler/lua54.can:674 -push("push", false) -- ./compiler/lua54.can:676 -end -- ./compiler/lua54.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 -if hasPush then -- ./compiler/lua54.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 -end -- ./compiler/lua54.can:680 -pop("push") -- ./compiler/lua54.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 -return r -- ./compiler/lua54.can:684 -end, -- ./compiler/lua54.can:684 -["DoExpr"] = function(t) -- ./compiler/lua54.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 -end -- ./compiler/lua54.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 -end, -- ./compiler/lua54.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 -end, -- ./compiler/lua54.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 -end, -- ./compiler/lua54.can:699 -["IfExpr"] = function(t) -- ./compiler/lua54.can:702 -for i = 2, # t do -- ./compiler/lua54.can:703 -local block = t[i] -- ./compiler/lua54.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:626 +["TableCompr"] = function(t) -- ./compiler/lua54.can:630 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 +end, -- ./compiler/lua54.can:631 +["Op"] = function(t) -- ./compiler/lua54.can:634 +local r -- ./compiler/lua54.can:635 +if # t == 2 then -- ./compiler/lua54.can:636 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 +else -- ./compiler/lua54.can:638 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 +end -- ./compiler/lua54.can:640 +else -- ./compiler/lua54.can:640 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 +else -- ./compiler/lua54.can:644 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +return r -- ./compiler/lua54.can:649 +end, -- ./compiler/lua54.can:649 +["Paren"] = function(t) -- ./compiler/lua54.can:652 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 +end, -- ./compiler/lua54.can:653 +["MethodStub"] = function(t) -- ./compiler/lua54.can:656 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 +end, -- ./compiler/lua54.can:662 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 +end, -- ./compiler/lua54.can:672 +["LetExpr"] = function(t) -- ./compiler/lua54.can:679 +return lua(t[1][1]) -- ./compiler/lua54.can:680 +end, -- ./compiler/lua54.can:680 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 +local r = "(function()" .. indent() -- ./compiler/lua54.can:686 +if hasPush then -- ./compiler/lua54.can:687 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 +else -- ./compiler/lua54.can:688 +push("push", false) -- ./compiler/lua54.can:690 +end -- ./compiler/lua54.can:690 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 +if hasPush then -- ./compiler/lua54.can:693 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 +end -- ./compiler/lua54.can:694 +pop("push") -- ./compiler/lua54.can:696 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 +return r -- ./compiler/lua54.can:698 +end, -- ./compiler/lua54.can:698 +["DoExpr"] = function(t) -- ./compiler/lua54.can:701 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 +end -- ./compiler/lua54.can:703 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 +end, -- ./compiler/lua54.can:705 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 end, -- ./compiler/lua54.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 end, -- ./compiler/lua54.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 -end, -- ./compiler/lua54.can:717 -["Call"] = function(t) -- ./compiler/lua54.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 -else -- ./compiler/lua54.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 -end -- ./compiler/lua54.can:730 -else -- ./compiler/lua54.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 -end -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["SafeCall"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 -else -- ./compiler/lua54.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 -end -- ./compiler/lua54.can:741 -end, -- ./compiler/lua54.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 -if start == nil then start = 1 end -- ./compiler/lua54.can:746 -local r -- ./compiler/lua54.can:747 -if t[start] then -- ./compiler/lua54.can:748 -r = lua(t[start]) -- ./compiler/lua54.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 -end -- ./compiler/lua54.can:751 +["IfExpr"] = function(t) -- ./compiler/lua54.can:716 +for i = 2, # t do -- ./compiler/lua54.can:717 +local block = t[i] -- ./compiler/lua54.can:718 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 +end, -- ./compiler/lua54.can:723 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 +end, -- ./compiler/lua54.can:727 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 +end, -- ./compiler/lua54.can:731 +["Call"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 +local replacement = macro["replacement"] -- ./compiler/lua54.can:742 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 +macroargs["..."] = (function() -- ./compiler/lua54.can:746 +local self = {} -- ./compiler/lua54.can:746 +for j = i + 1, # t do -- ./compiler/lua54.can:746 +self[#self+1] = t[j] -- ./compiler/lua54.can:746 +end -- ./compiler/lua54.can:746 +return self -- ./compiler/lua54.can:746 +end)() -- ./compiler/lua54.can:746 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 +if t[i + 1] == nil then -- ./compiler/lua54.can:748 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 +end -- ./compiler/lua54.can:749 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 else -- ./compiler/lua54.can:751 -r = "" -- ./compiler/lua54.can:754 -end -- ./compiler/lua54.can:754 -return r -- ./compiler/lua54.can:756 -end, -- ./compiler/lua54.can:756 -["Id"] = function(t) -- ./compiler/lua54.can:759 -return t[1] -- ./compiler/lua54.can:760 -end, -- ./compiler/lua54.can:760 -["AttributeId"] = function(t) -- ./compiler/lua54.can:763 -if t[2] then -- ./compiler/lua54.can:764 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 -else -- ./compiler/lua54.can:765 -return t[1] -- ./compiler/lua54.can:767 -end -- ./compiler/lua54.can:767 -end, -- ./compiler/lua54.can:767 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 -if t["id"] then -- ./compiler/lua54.can:772 -return t["id"] -- ./compiler/lua54.can:773 -else -- ./compiler/lua54.can:773 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 -for j = 1, # t, 1 do -- ./compiler/lua54.can:777 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 -end -- ./compiler/lua54.can:778 -table["insert"](d, vars) -- ./compiler/lua54.can:780 -t["id"] = vars["id"] -- ./compiler/lua54.can:781 -return vars["id"] -- ./compiler/lua54.can:782 -end -- ./compiler/lua54.can:782 -end, -- ./compiler/lua54.can:782 -["Index"] = function(t) -- ./compiler/lua54.can:786 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 -else -- ./compiler/lua54.can:788 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +push("macroargs", macroargs) -- ./compiler/lua54.can:756 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 +local r = lua(replacement) -- ./compiler/lua54.can:758 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 +pop("macroargs") -- ./compiler/lua54.can:760 +return r -- ./compiler/lua54.can:761 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 +else -- ./compiler/lua54.can:764 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 +end -- ./compiler/lua54.can:766 +else -- ./compiler/lua54.can:766 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +end -- ./compiler/lua54.can:769 +end, -- ./compiler/lua54.can:769 +["SafeCall"] = function(t) -- ./compiler/lua54.can:773 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +else -- ./compiler/lua54.can:775 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +end -- ./compiler/lua54.can:777 +end, -- ./compiler/lua54.can:777 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 +if start == nil then start = 1 end -- ./compiler/lua54.can:782 +local r -- ./compiler/lua54.can:783 +if t[start] then -- ./compiler/lua54.can:784 +r = lua(t[start]) -- ./compiler/lua54.can:785 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 +end -- ./compiler/lua54.can:787 +else -- ./compiler/lua54.can:787 +r = "" -- ./compiler/lua54.can:790 end -- ./compiler/lua54.can:790 -end, -- ./compiler/lua54.can:790 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 -local l = {} -- ./compiler/lua54.can:796 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 -table["insert"](l, 1, t) -- ./compiler/lua54.can:798 -t = t[1] -- ./compiler/lua54.can:799 -end -- ./compiler/lua54.can:799 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 -for _, e in ipairs(l) do -- ./compiler/lua54.can:802 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 -else -- ./compiler/lua54.can:805 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +return r -- ./compiler/lua54.can:792 +end, -- ./compiler/lua54.can:792 +["Id"] = function(t) -- ./compiler/lua54.can:795 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 +local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:802 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 +local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 +return r -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 -return r -- ./compiler/lua54.can:811 -else -- ./compiler/lua54.can:811 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 -end -- ./compiler/lua54.can:813 -end, -- ./compiler/lua54.can:813 -["_opid"] = { -- ./compiler/lua54.can:818 -["add"] = "+", -- ./compiler/lua54.can:819 -["sub"] = "-", -- ./compiler/lua54.can:819 -["mul"] = "*", -- ./compiler/lua54.can:819 -["div"] = "/", -- ./compiler/lua54.can:819 -["idiv"] = "//", -- ./compiler/lua54.can:820 -["mod"] = "%", -- ./compiler/lua54.can:820 -["pow"] = "^", -- ./compiler/lua54.can:820 -["concat"] = "..", -- ./compiler/lua54.can:820 -["band"] = "&", -- ./compiler/lua54.can:821 -["bor"] = "|", -- ./compiler/lua54.can:821 -["bxor"] = "~", -- ./compiler/lua54.can:821 -["shl"] = "<<", -- ./compiler/lua54.can:821 -["shr"] = ">>", -- ./compiler/lua54.can:821 -["eq"] = "==", -- ./compiler/lua54.can:822 -["ne"] = "~=", -- ./compiler/lua54.can:822 -["lt"] = "<", -- ./compiler/lua54.can:822 -["gt"] = ">", -- ./compiler/lua54.can:822 -["le"] = "<=", -- ./compiler/lua54.can:822 -["ge"] = ">=", -- ./compiler/lua54.can:822 -["and"] = "and", -- ./compiler/lua54.can:823 -["or"] = "or", -- ./compiler/lua54.can:823 -["unm"] = "-", -- ./compiler/lua54.can:823 -["len"] = "#", -- ./compiler/lua54.can:823 -["bnot"] = "~", -- ./compiler/lua54.can:823 -["not"] = "not" -- ./compiler/lua54.can:823 -} -- ./compiler/lua54.can:823 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 -end }) -- ./compiler/lua54.can:827 +return t[1] -- ./compiler/lua54.can:810 +end, -- ./compiler/lua54.can:810 +["AttributeId"] = function(t) -- ./compiler/lua54.can:813 +if t[2] then -- ./compiler/lua54.can:814 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 +else -- ./compiler/lua54.can:815 +return t[1] -- ./compiler/lua54.can:817 +end -- ./compiler/lua54.can:817 +end, -- ./compiler/lua54.can:817 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 +if t["id"] then -- ./compiler/lua54.can:822 +return t["id"] -- ./compiler/lua54.can:823 +else -- ./compiler/lua54.can:823 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 +for j = 1, # t, 1 do -- ./compiler/lua54.can:827 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 +end -- ./compiler/lua54.can:828 +table["insert"](d, vars) -- ./compiler/lua54.can:830 +t["id"] = vars["id"] -- ./compiler/lua54.can:831 +return vars["id"] -- ./compiler/lua54.can:832 +end -- ./compiler/lua54.can:832 +end, -- ./compiler/lua54.can:832 +["Index"] = function(t) -- ./compiler/lua54.can:836 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 +else -- ./compiler/lua54.can:838 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 +end -- ./compiler/lua54.can:840 +end, -- ./compiler/lua54.can:840 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 +local l = {} -- ./compiler/lua54.can:846 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 +table["insert"](l, 1, t) -- ./compiler/lua54.can:848 +t = t[1] -- ./compiler/lua54.can:849 +end -- ./compiler/lua54.can:849 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 +for _, e in ipairs(l) do -- ./compiler/lua54.can:852 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 +else -- ./compiler/lua54.can:855 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 +return r -- ./compiler/lua54.can:861 +else -- ./compiler/lua54.can:861 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 +end -- ./compiler/lua54.can:863 +end, -- ./compiler/lua54.can:863 +["_opid"] = { -- ./compiler/lua54.can:868 +["add"] = "+", -- ./compiler/lua54.can:869 +["sub"] = "-", -- ./compiler/lua54.can:869 +["mul"] = "*", -- ./compiler/lua54.can:869 +["div"] = "/", -- ./compiler/lua54.can:869 +["idiv"] = "//", -- ./compiler/lua54.can:870 +["mod"] = "%", -- ./compiler/lua54.can:870 +["pow"] = "^", -- ./compiler/lua54.can:870 +["concat"] = "..", -- ./compiler/lua54.can:870 +["band"] = "&", -- ./compiler/lua54.can:871 +["bor"] = "|", -- ./compiler/lua54.can:871 +["bxor"] = "~", -- ./compiler/lua54.can:871 +["shl"] = "<<", -- ./compiler/lua54.can:871 +["shr"] = ">>", -- ./compiler/lua54.can:871 +["eq"] = "==", -- ./compiler/lua54.can:872 +["ne"] = "~=", -- ./compiler/lua54.can:872 +["lt"] = "<", -- ./compiler/lua54.can:872 +["gt"] = ">", -- ./compiler/lua54.can:872 +["le"] = "<=", -- ./compiler/lua54.can:872 +["ge"] = ">=", -- ./compiler/lua54.can:872 +["and"] = "and", -- ./compiler/lua54.can:873 +["or"] = "or", -- ./compiler/lua54.can:873 +["unm"] = "-", -- ./compiler/lua54.can:873 +["len"] = "#", -- ./compiler/lua54.can:873 +["bnot"] = "~", -- ./compiler/lua54.can:873 +["not"] = "not" -- ./compiler/lua54.can:873 +} -- ./compiler/lua54.can:873 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 +end }) -- ./compiler/lua54.can:877 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -3687,11 +3940,11 @@ tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 end -- ./compiler/luajit.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 -return requireStr .. code -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 +return requireStr .. code -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +local lua54 = _() or lua54 -- ./compiler/lua54.can:889 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -3707,861 +3960,921 @@ local function _() -- ./compiler/luajit.can:48 local function _() -- ./compiler/luajit.can:50 local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 -local targetName = "Lua 5.4" -- ./compiler/lua54.can:1 -return function(code, ast, options) -- ./compiler/lua54.can:3 -local lastInputPos = 1 -- ./compiler/lua54.can:5 -local prevLinePos = 1 -- ./compiler/lua54.can:6 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:7 -local lastLine = 1 -- ./compiler/lua54.can:8 -local indentLevel = 0 -- ./compiler/lua54.can:11 -local function newline() -- ./compiler/lua54.can:13 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:14 -if options["mapLines"] then -- ./compiler/lua54.can:15 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:16 +local util = require("candran.util") -- ./compiler/lua54.can:1 +local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 +return function(code, ast, options, macros) -- ./compiler/lua54.can:5 +if macros == nil then macros = { -- ./compiler/lua54.can:5 +["functions"] = {}, -- ./compiler/lua54.can:5 +["variables"] = {} -- ./compiler/lua54.can:5 +} end -- ./compiler/lua54.can:5 +local lastInputPos = 1 -- ./compiler/lua54.can:7 +local prevLinePos = 1 -- ./compiler/lua54.can:8 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 +local lastLine = 1 -- ./compiler/lua54.can:10 +local indentLevel = 0 -- ./compiler/lua54.can:13 +local function newline() -- ./compiler/lua54.can:15 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 +if options["mapLines"] then -- ./compiler/lua54.can:17 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:17 -if source and line then -- ./compiler/lua54.can:19 -lastSource = source -- ./compiler/lua54.can:20 -lastLine = tonumber(line) -- ./compiler/lua54.can:21 -else -- ./compiler/lua54.can:21 +") -- ./compiler/lua54.can:19 +if source and line then -- ./compiler/lua54.can:21 +lastSource = source -- ./compiler/lua54.can:22 +lastLine = tonumber(line) -- ./compiler/lua54.can:23 +else -- ./compiler/lua54.can:23 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:23 -lastLine = lastLine + (1) -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -end -- ./compiler/lua54.can:24 -prevLinePos = lastInputPos -- ./compiler/lua54.can:28 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:30 -end -- ./compiler/lua54.can:30 -return r -- ./compiler/lua54.can:32 +") do -- ./compiler/lua54.can:25 +lastLine = lastLine + (1) -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +end -- ./compiler/lua54.can:26 +prevLinePos = lastInputPos -- ./compiler/lua54.can:30 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 end -- ./compiler/lua54.can:32 -local function indent() -- ./compiler/lua54.can:35 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:36 -return newline() -- ./compiler/lua54.can:37 -end -- ./compiler/lua54.can:37 -local function unindent() -- ./compiler/lua54.can:40 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:41 -return newline() -- ./compiler/lua54.can:42 -end -- ./compiler/lua54.can:42 -local states = { -- ./compiler/lua54.can:47 -["push"] = {}, -- ./compiler/lua54.can:48 -["destructuring"] = {}, -- ./compiler/lua54.can:49 -["scope"] = {} -- ./compiler/lua54.can:50 -} -- ./compiler/lua54.can:50 -local function push(name, state) -- ./compiler/lua54.can:53 -table["insert"](states[name], state) -- ./compiler/lua54.can:54 -return "" -- ./compiler/lua54.can:55 -end -- ./compiler/lua54.can:55 -local function pop(name) -- ./compiler/lua54.can:58 -table["remove"](states[name]) -- ./compiler/lua54.can:59 -return "" -- ./compiler/lua54.can:60 -end -- ./compiler/lua54.can:60 -local function set(name, state) -- ./compiler/lua54.can:63 -states[name][# states[name]] = state -- ./compiler/lua54.can:64 -return "" -- ./compiler/lua54.can:65 -end -- ./compiler/lua54.can:65 -local function peek(name) -- ./compiler/lua54.can:68 -return states[name][# states[name]] -- ./compiler/lua54.can:69 -end -- ./compiler/lua54.can:69 -local function var(name) -- ./compiler/lua54.can:74 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:75 -end -- ./compiler/lua54.can:75 -local function tmp() -- ./compiler/lua54.can:79 -local scope = peek("scope") -- ./compiler/lua54.can:80 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:81 -table["insert"](scope, var) -- ./compiler/lua54.can:82 -return var -- ./compiler/lua54.can:83 -end -- ./compiler/lua54.can:83 -local required = {} -- ./compiler/lua54.can:87 -local requireStr = "" -- ./compiler/lua54.can:88 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:90 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:91 -if not required[req] then -- ./compiler/lua54.can:92 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:93 -required[req] = true -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -end -- ./compiler/lua54.can:94 -local loop = { -- ./compiler/lua54.can:99 -"While", -- ./compiler/lua54.can:99 -"Repeat", -- ./compiler/lua54.can:99 -"Fornum", -- ./compiler/lua54.can:99 -"Forin", -- ./compiler/lua54.can:99 -"WhileExpr", -- ./compiler/lua54.can:99 -"RepeatExpr", -- ./compiler/lua54.can:99 -"FornumExpr", -- ./compiler/lua54.can:99 -"ForinExpr" -- ./compiler/lua54.can:99 -} -- ./compiler/lua54.can:99 -local func = { -- ./compiler/lua54.can:100 -"Function", -- ./compiler/lua54.can:100 -"TableCompr", -- ./compiler/lua54.can:100 -"DoExpr", -- ./compiler/lua54.can:100 -"WhileExpr", -- ./compiler/lua54.can:100 -"RepeatExpr", -- ./compiler/lua54.can:100 -"IfExpr", -- ./compiler/lua54.can:100 -"FornumExpr", -- ./compiler/lua54.can:100 -"ForinExpr" -- ./compiler/lua54.can:100 -} -- ./compiler/lua54.can:100 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:104 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:104 -local tagsCheck = {} -- ./compiler/lua54.can:105 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:106 -tagsCheck[tag] = true -- ./compiler/lua54.can:107 -end -- ./compiler/lua54.can:107 -local nofollowCheck = {} -- ./compiler/lua54.can:109 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:110 -nofollowCheck[tag] = true -- ./compiler/lua54.can:111 -end -- ./compiler/lua54.can:111 -for _, node in ipairs(list) do -- ./compiler/lua54.can:113 -if type(node) == "table" then -- ./compiler/lua54.can:114 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:115 -return node -- ./compiler/lua54.can:116 -end -- ./compiler/lua54.can:116 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:118 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:119 -if r then -- ./compiler/lua54.can:120 -return r -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -end -- ./compiler/lua54.can:120 -return nil -- ./compiler/lua54.can:124 -end -- ./compiler/lua54.can:124 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:129 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:129 -local tagsCheck = {} -- ./compiler/lua54.can:130 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:131 -tagsCheck[tag] = true -- ./compiler/lua54.can:132 -end -- ./compiler/lua54.can:132 -local nofollowCheck = {} -- ./compiler/lua54.can:134 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:135 -nofollowCheck[tag] = true -- ./compiler/lua54.can:136 -end -- ./compiler/lua54.can:136 -local found = {} -- ./compiler/lua54.can:138 -for _, node in ipairs(list) do -- ./compiler/lua54.can:139 -if type(node) == "table" then -- ./compiler/lua54.can:140 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:141 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:142 -table["insert"](found, n) -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -end -- ./compiler/lua54.can:143 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:146 -table["insert"](found, node) -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -end -- ./compiler/lua54.can:147 -return found -- ./compiler/lua54.can:151 -end -- ./compiler/lua54.can:151 -local function all(list, tags) -- ./compiler/lua54.can:155 -for _, node in ipairs(list) do -- ./compiler/lua54.can:156 -local ok = false -- ./compiler/lua54.can:157 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:158 -if node["tag"] == tag then -- ./compiler/lua54.can:159 -ok = true -- ./compiler/lua54.can:160 -break -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -end -- ./compiler/lua54.can:161 -if not ok then -- ./compiler/lua54.can:164 -return false -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -end -- ./compiler/lua54.can:165 -return true -- ./compiler/lua54.can:168 -end -- ./compiler/lua54.can:168 -local tags -- ./compiler/lua54.can:172 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:174 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:175 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:176 -end -- ./compiler/lua54.can:176 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:178 -end -- ./compiler/lua54.can:178 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:182 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:183 -end -- ./compiler/lua54.can:183 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:185 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:186 -end -- ./compiler/lua54.can:186 -local CONTINUE_START = function() -- ./compiler/lua54.can:188 -return "do" .. indent() -- ./compiler/lua54.can:189 +return r -- ./compiler/lua54.can:34 +end -- ./compiler/lua54.can:34 +local function indent() -- ./compiler/lua54.can:37 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 +return newline() -- ./compiler/lua54.can:39 +end -- ./compiler/lua54.can:39 +local function unindent() -- ./compiler/lua54.can:42 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 +return newline() -- ./compiler/lua54.can:44 +end -- ./compiler/lua54.can:44 +local states = { -- ./compiler/lua54.can:49 +["push"] = {}, -- ./compiler/lua54.can:50 +["destructuring"] = {}, -- ./compiler/lua54.can:51 +["scope"] = {}, -- ./compiler/lua54.can:52 +["macroargs"] = {} -- ./compiler/lua54.can:53 +} -- ./compiler/lua54.can:53 +local function push(name, state) -- ./compiler/lua54.can:56 +table["insert"](states[name], state) -- ./compiler/lua54.can:57 +return "" -- ./compiler/lua54.can:58 +end -- ./compiler/lua54.can:58 +local function pop(name) -- ./compiler/lua54.can:61 +table["remove"](states[name]) -- ./compiler/lua54.can:62 +return "" -- ./compiler/lua54.can:63 +end -- ./compiler/lua54.can:63 +local function set(name, state) -- ./compiler/lua54.can:66 +states[name][# states[name]] = state -- ./compiler/lua54.can:67 +return "" -- ./compiler/lua54.can:68 +end -- ./compiler/lua54.can:68 +local function peek(name) -- ./compiler/lua54.can:71 +return states[name][# states[name]] -- ./compiler/lua54.can:72 +end -- ./compiler/lua54.can:72 +local function var(name) -- ./compiler/lua54.can:77 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 +end -- ./compiler/lua54.can:78 +local function tmp() -- ./compiler/lua54.can:82 +local scope = peek("scope") -- ./compiler/lua54.can:83 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 +table["insert"](scope, var) -- ./compiler/lua54.can:85 +return var -- ./compiler/lua54.can:86 +end -- ./compiler/lua54.can:86 +local nomacro = { -- ./compiler/lua54.can:90 +["variables"] = {}, -- ./compiler/lua54.can:90 +["functions"] = {} -- ./compiler/lua54.can:90 +} -- ./compiler/lua54.can:90 +local required = {} -- ./compiler/lua54.can:93 +local requireStr = "" -- ./compiler/lua54.can:94 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 +if not required[req] then -- ./compiler/lua54.can:98 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 +required[req] = true -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +end -- ./compiler/lua54.can:100 +local loop = { -- ./compiler/lua54.can:105 +"While", -- ./compiler/lua54.can:105 +"Repeat", -- ./compiler/lua54.can:105 +"Fornum", -- ./compiler/lua54.can:105 +"Forin", -- ./compiler/lua54.can:105 +"WhileExpr", -- ./compiler/lua54.can:105 +"RepeatExpr", -- ./compiler/lua54.can:105 +"FornumExpr", -- ./compiler/lua54.can:105 +"ForinExpr" -- ./compiler/lua54.can:105 +} -- ./compiler/lua54.can:105 +local func = { -- ./compiler/lua54.can:106 +"Function", -- ./compiler/lua54.can:106 +"TableCompr", -- ./compiler/lua54.can:106 +"DoExpr", -- ./compiler/lua54.can:106 +"WhileExpr", -- ./compiler/lua54.can:106 +"RepeatExpr", -- ./compiler/lua54.can:106 +"IfExpr", -- ./compiler/lua54.can:106 +"FornumExpr", -- ./compiler/lua54.can:106 +"ForinExpr" -- ./compiler/lua54.can:106 +} -- ./compiler/lua54.can:106 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 +local tagsCheck = {} -- ./compiler/lua54.can:111 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 +tagsCheck[tag] = true -- ./compiler/lua54.can:113 +end -- ./compiler/lua54.can:113 +local nofollowCheck = {} -- ./compiler/lua54.can:115 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 +nofollowCheck[tag] = true -- ./compiler/lua54.can:117 +end -- ./compiler/lua54.can:117 +for _, node in ipairs(list) do -- ./compiler/lua54.can:119 +if type(node) == "table" then -- ./compiler/lua54.can:120 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 +return node -- ./compiler/lua54.can:122 +end -- ./compiler/lua54.can:122 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 +if r then -- ./compiler/lua54.can:126 +return r -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +end -- ./compiler/lua54.can:126 +return nil -- ./compiler/lua54.can:130 +end -- ./compiler/lua54.can:130 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 +local tagsCheck = {} -- ./compiler/lua54.can:136 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 +tagsCheck[tag] = true -- ./compiler/lua54.can:138 +end -- ./compiler/lua54.can:138 +local nofollowCheck = {} -- ./compiler/lua54.can:140 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 +nofollowCheck[tag] = true -- ./compiler/lua54.can:142 +end -- ./compiler/lua54.can:142 +local found = {} -- ./compiler/lua54.can:144 +for _, node in ipairs(list) do -- ./compiler/lua54.can:145 +if type(node) == "table" then -- ./compiler/lua54.can:146 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 +table["insert"](found, n) -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +end -- ./compiler/lua54.can:149 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 +table["insert"](found, node) -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +end -- ./compiler/lua54.can:153 +return found -- ./compiler/lua54.can:157 +end -- ./compiler/lua54.can:157 +local function all(list, tags) -- ./compiler/lua54.can:161 +for _, node in ipairs(list) do -- ./compiler/lua54.can:162 +local ok = false -- ./compiler/lua54.can:163 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 +if node["tag"] == tag then -- ./compiler/lua54.can:165 +ok = true -- ./compiler/lua54.can:166 +break -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +end -- ./compiler/lua54.can:167 +if not ok then -- ./compiler/lua54.can:170 +return false -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +end -- ./compiler/lua54.can:171 +return true -- ./compiler/lua54.can:174 +end -- ./compiler/lua54.can:174 +local tags -- ./compiler/lua54.can:178 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 +end -- ./compiler/lua54.can:182 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +end -- ./compiler/lua54.can:184 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 end -- ./compiler/lua54.can:189 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:191 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:192 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 end -- ./compiler/lua54.can:192 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:194 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:194 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:194 -local vars = {} -- ./compiler/lua54.can:195 -local values = {} -- ./compiler/lua54.can:196 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:197 -for _, v in ipairs(list) do -- ./compiler/lua54.can:198 -local var, val -- ./compiler/lua54.can:199 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:200 -var = v -- ./compiler/lua54.can:201 -val = { -- ./compiler/lua54.can:202 -["tag"] = "Index", -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "Id", -- ./compiler/lua54.can:202 -list["id"] -- ./compiler/lua54.can:202 -}, -- ./compiler/lua54.can:202 -{ -- ./compiler/lua54.can:202 -["tag"] = "String", -- ./compiler/lua54.can:202 -v[1] -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -} -- ./compiler/lua54.can:202 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:203 -var = v[2] -- ./compiler/lua54.can:204 -val = { -- ./compiler/lua54.can:205 -["tag"] = "Index", -- ./compiler/lua54.can:205 -{ -- ./compiler/lua54.can:205 -["tag"] = "Id", -- ./compiler/lua54.can:205 -list["id"] -- ./compiler/lua54.can:205 -}, -- ./compiler/lua54.can:205 -v[1] -- ./compiler/lua54.can:205 -} -- ./compiler/lua54.can:205 -else -- ./compiler/lua54.can:205 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:207 -end -- ./compiler/lua54.can:207 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:209 -val = { -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["rightOp"], -- ./compiler/lua54.can:210 -var, -- ./compiler/lua54.can:210 -{ -- ./compiler/lua54.can:210 -["tag"] = "Op", -- ./compiler/lua54.can:210 -destructured["leftOp"], -- ./compiler/lua54.can:210 -val, -- ./compiler/lua54.can:210 -var -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -} -- ./compiler/lua54.can:210 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:211 -val = { -- ./compiler/lua54.can:212 -["tag"] = "Op", -- ./compiler/lua54.can:212 -destructured["rightOp"], -- ./compiler/lua54.can:212 -var, -- ./compiler/lua54.can:212 -val -- ./compiler/lua54.can:212 -} -- ./compiler/lua54.can:212 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:213 -val = { -- ./compiler/lua54.can:214 -["tag"] = "Op", -- ./compiler/lua54.can:214 -destructured["leftOp"], -- ./compiler/lua54.can:214 -val, -- ./compiler/lua54.can:214 -var -- ./compiler/lua54.can:214 -} -- ./compiler/lua54.can:214 -end -- ./compiler/lua54.can:214 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:216 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -end -- ./compiler/lua54.can:217 -if # vars > 0 then -- ./compiler/lua54.can:220 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:221 -if newlineAfter then -- ./compiler/lua54.can:222 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:223 -else -- ./compiler/lua54.can:223 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:225 -end -- ./compiler/lua54.can:225 -else -- ./compiler/lua54.can:225 -return "" -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -end -- ./compiler/lua54.can:228 -tags = setmetatable({ -- ./compiler/lua54.can:233 -["Block"] = function(t) -- ./compiler/lua54.can:235 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:236 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:237 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:238 -hasPush = false -- ./compiler/lua54.can:239 -end -- ./compiler/lua54.can:239 -local r = push("scope", {}) -- ./compiler/lua54.can:241 -if hasPush then -- ./compiler/lua54.can:242 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:243 -end -- ./compiler/lua54.can:243 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:245 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:246 -end -- ./compiler/lua54.can:246 -if t[# t] then -- ./compiler/lua54.can:248 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:249 +local CONTINUE_START = function() -- ./compiler/lua54.can:194 +return "do" .. indent() -- ./compiler/lua54.can:195 +end -- ./compiler/lua54.can:195 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 +end -- ./compiler/lua54.can:198 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 +local vars = {} -- ./compiler/lua54.can:201 +local values = {} -- ./compiler/lua54.can:202 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 +for _, v in ipairs(list) do -- ./compiler/lua54.can:204 +local var, val -- ./compiler/lua54.can:205 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 +var = v -- ./compiler/lua54.can:207 +val = { -- ./compiler/lua54.can:208 +["tag"] = "Index", -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "Id", -- ./compiler/lua54.can:208 +list["id"] -- ./compiler/lua54.can:208 +}, -- ./compiler/lua54.can:208 +{ -- ./compiler/lua54.can:208 +["tag"] = "String", -- ./compiler/lua54.can:208 +v[1] -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +} -- ./compiler/lua54.can:208 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 +var = v[2] -- ./compiler/lua54.can:210 +val = { -- ./compiler/lua54.can:211 +["tag"] = "Index", -- ./compiler/lua54.can:211 +{ -- ./compiler/lua54.can:211 +["tag"] = "Id", -- ./compiler/lua54.can:211 +list["id"] -- ./compiler/lua54.can:211 +}, -- ./compiler/lua54.can:211 +v[1] -- ./compiler/lua54.can:211 +} -- ./compiler/lua54.can:211 +else -- ./compiler/lua54.can:211 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 +end -- ./compiler/lua54.can:213 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 +val = { -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["rightOp"], -- ./compiler/lua54.can:216 +var, -- ./compiler/lua54.can:216 +{ -- ./compiler/lua54.can:216 +["tag"] = "Op", -- ./compiler/lua54.can:216 +destructured["leftOp"], -- ./compiler/lua54.can:216 +val, -- ./compiler/lua54.can:216 +var -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +} -- ./compiler/lua54.can:216 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +val = { -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["rightOp"], -- ./compiler/lua54.can:218 +var, -- ./compiler/lua54.can:218 +val -- ./compiler/lua54.can:218 +} -- ./compiler/lua54.can:218 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +val = { -- ./compiler/lua54.can:220 +["tag"] = "Op", -- ./compiler/lua54.can:220 +destructured["leftOp"], -- ./compiler/lua54.can:220 +val, -- ./compiler/lua54.can:220 +var -- ./compiler/lua54.can:220 +} -- ./compiler/lua54.can:220 +end -- ./compiler/lua54.can:220 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +end -- ./compiler/lua54.can:223 +if # vars > 0 then -- ./compiler/lua54.can:226 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 +if newlineAfter then -- ./compiler/lua54.can:228 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 +else -- ./compiler/lua54.can:229 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 +end -- ./compiler/lua54.can:231 +else -- ./compiler/lua54.can:231 +return "" -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +end -- ./compiler/lua54.can:234 +tags = setmetatable({ -- ./compiler/lua54.can:239 +["Block"] = function(t) -- ./compiler/lua54.can:241 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 +hasPush = false -- ./compiler/lua54.can:245 +end -- ./compiler/lua54.can:245 +local r = push("scope", {}) -- ./compiler/lua54.can:247 +if hasPush then -- ./compiler/lua54.can:248 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 end -- ./compiler/lua54.can:249 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:251 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:252 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 end -- ./compiler/lua54.can:252 -return r .. pop("scope") -- ./compiler/lua54.can:254 -end, -- ./compiler/lua54.can:254 -["Do"] = function(t) -- ./compiler/lua54.can:260 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:261 -end, -- ./compiler/lua54.can:261 -["Set"] = function(t) -- ./compiler/lua54.can:264 -local expr = t[# t] -- ./compiler/lua54.can:266 -local vars, values = {}, {} -- ./compiler/lua54.can:267 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:268 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:269 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:270 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:271 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:272 -else -- ./compiler/lua54.can:272 -table["insert"](vars, n) -- ./compiler/lua54.can:274 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -end -- ./compiler/lua54.can:275 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:279 -local r = "" -- ./compiler/lua54.can:280 -if # vars > 0 then -- ./compiler/lua54.can:281 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:282 -end -- ./compiler/lua54.can:282 -if # destructuringVars > 0 then -- ./compiler/lua54.can:284 -local destructured = {} -- ./compiler/lua54.can:285 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:286 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:287 -end -- ./compiler/lua54.can:287 -return r -- ./compiler/lua54.can:289 -elseif # t == 4 then -- ./compiler/lua54.can:290 -if t[3] == "=" then -- ./compiler/lua54.can:291 -local r = "" -- ./compiler/lua54.can:292 -if # vars > 0 then -- ./compiler/lua54.can:293 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:294 -t[2], -- ./compiler/lua54.can:294 -vars[1], -- ./compiler/lua54.can:294 -{ -- ./compiler/lua54.can:294 -["tag"] = "Paren", -- ./compiler/lua54.can:294 -values[1] -- ./compiler/lua54.can:294 -} -- ./compiler/lua54.can:294 -}, "Op")) -- ./compiler/lua54.can:294 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:295 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:296 -t[2], -- ./compiler/lua54.can:296 -vars[i], -- ./compiler/lua54.can:296 -{ -- ./compiler/lua54.can:296 -["tag"] = "Paren", -- ./compiler/lua54.can:296 -values[i] -- ./compiler/lua54.can:296 -} -- ./compiler/lua54.can:296 -}, "Op")) -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -end -- ./compiler/lua54.can:296 -if # destructuringVars > 0 then -- ./compiler/lua54.can:299 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:300 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:301 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:302 +if t[# t] then -- ./compiler/lua54.can:254 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 +end -- ./compiler/lua54.can:255 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 +end -- ./compiler/lua54.can:258 +return r .. pop("scope") -- ./compiler/lua54.can:260 +end, -- ./compiler/lua54.can:260 +["Do"] = function(t) -- ./compiler/lua54.can:266 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 +end, -- ./compiler/lua54.can:267 +["Set"] = function(t) -- ./compiler/lua54.can:270 +local expr = t[# t] -- ./compiler/lua54.can:272 +local vars, values = {}, {} -- ./compiler/lua54.can:273 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 +else -- ./compiler/lua54.can:278 +table["insert"](vars, n) -- ./compiler/lua54.can:280 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +end -- ./compiler/lua54.can:281 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 +local r = "" -- ./compiler/lua54.can:286 +if # vars > 0 then -- ./compiler/lua54.can:287 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 +end -- ./compiler/lua54.can:288 +if # destructuringVars > 0 then -- ./compiler/lua54.can:290 +local destructured = {} -- ./compiler/lua54.can:291 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 +end -- ./compiler/lua54.can:293 +return r -- ./compiler/lua54.can:295 +elseif # t == 4 then -- ./compiler/lua54.can:296 +if t[3] == "=" then -- ./compiler/lua54.can:297 +local r = "" -- ./compiler/lua54.can:298 +if # vars > 0 then -- ./compiler/lua54.can:299 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 +t[2], -- ./compiler/lua54.can:300 +vars[1], -- ./compiler/lua54.can:300 +{ -- ./compiler/lua54.can:300 +["tag"] = "Paren", -- ./compiler/lua54.can:300 +values[1] -- ./compiler/lua54.can:300 +} -- ./compiler/lua54.can:300 +}, "Op")) -- ./compiler/lua54.can:300 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +t[2], -- ./compiler/lua54.can:302 +vars[i], -- ./compiler/lua54.can:302 +{ -- ./compiler/lua54.can:302 +["tag"] = "Paren", -- ./compiler/lua54.can:302 +values[i] -- ./compiler/lua54.can:302 +} -- ./compiler/lua54.can:302 +}, "Op")) -- ./compiler/lua54.can:302 end -- ./compiler/lua54.can:302 -return r -- ./compiler/lua54.can:304 -else -- ./compiler/lua54.can:304 -local r = "" -- ./compiler/lua54.can:306 -if # vars > 0 then -- ./compiler/lua54.can:307 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:308 -t[3], -- ./compiler/lua54.can:308 -{ -- ./compiler/lua54.can:308 -["tag"] = "Paren", -- ./compiler/lua54.can:308 -values[1] -- ./compiler/lua54.can:308 -}, -- ./compiler/lua54.can:308 -vars[1] -- ./compiler/lua54.can:308 -}, "Op")) -- ./compiler/lua54.can:308 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:309 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:310 -t[3], -- ./compiler/lua54.can:310 -{ -- ./compiler/lua54.can:310 -["tag"] = "Paren", -- ./compiler/lua54.can:310 -values[i] -- ./compiler/lua54.can:310 -}, -- ./compiler/lua54.can:310 -vars[i] -- ./compiler/lua54.can:310 -}, "Op")) -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -end -- ./compiler/lua54.can:310 -if # destructuringVars > 0 then -- ./compiler/lua54.can:313 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:314 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:315 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:316 +end -- ./compiler/lua54.can:302 +if # destructuringVars > 0 then -- ./compiler/lua54.can:305 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 +end -- ./compiler/lua54.can:308 +return r -- ./compiler/lua54.can:310 +else -- ./compiler/lua54.can:310 +local r = "" -- ./compiler/lua54.can:312 +if # vars > 0 then -- ./compiler/lua54.can:313 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 +t[3], -- ./compiler/lua54.can:314 +{ -- ./compiler/lua54.can:314 +["tag"] = "Paren", -- ./compiler/lua54.can:314 +values[1] -- ./compiler/lua54.can:314 +}, -- ./compiler/lua54.can:314 +vars[1] -- ./compiler/lua54.can:314 +}, "Op")) -- ./compiler/lua54.can:314 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +t[3], -- ./compiler/lua54.can:316 +{ -- ./compiler/lua54.can:316 +["tag"] = "Paren", -- ./compiler/lua54.can:316 +values[i] -- ./compiler/lua54.can:316 +}, -- ./compiler/lua54.can:316 +vars[i] -- ./compiler/lua54.can:316 +}, "Op")) -- ./compiler/lua54.can:316 end -- ./compiler/lua54.can:316 -return r -- ./compiler/lua54.can:318 -end -- ./compiler/lua54.can:318 -else -- ./compiler/lua54.can:318 -local r = "" -- ./compiler/lua54.can:321 -if # vars > 0 then -- ./compiler/lua54.can:322 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:323 -t[2], -- ./compiler/lua54.can:323 -vars[1], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Op", -- ./compiler/lua54.can:323 -t[4], -- ./compiler/lua54.can:323 -{ -- ./compiler/lua54.can:323 -["tag"] = "Paren", -- ./compiler/lua54.can:323 -values[1] -- ./compiler/lua54.can:323 -}, -- ./compiler/lua54.can:323 -vars[1] -- ./compiler/lua54.can:323 -} -- ./compiler/lua54.can:323 -}, "Op")) -- ./compiler/lua54.can:323 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:324 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:325 -t[2], -- ./compiler/lua54.can:325 -vars[i], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Op", -- ./compiler/lua54.can:325 -t[4], -- ./compiler/lua54.can:325 -{ -- ./compiler/lua54.can:325 -["tag"] = "Paren", -- ./compiler/lua54.can:325 -values[i] -- ./compiler/lua54.can:325 -}, -- ./compiler/lua54.can:325 -vars[i] -- ./compiler/lua54.can:325 -} -- ./compiler/lua54.can:325 -}, "Op")) -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -end -- ./compiler/lua54.can:325 -if # destructuringVars > 0 then -- ./compiler/lua54.can:328 -local destructured = { -- ./compiler/lua54.can:329 -["rightOp"] = t[2], -- ./compiler/lua54.can:329 -["leftOp"] = t[4] -- ./compiler/lua54.can:329 +end -- ./compiler/lua54.can:316 +if # destructuringVars > 0 then -- ./compiler/lua54.can:319 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 +end -- ./compiler/lua54.can:322 +return r -- ./compiler/lua54.can:324 +end -- ./compiler/lua54.can:324 +else -- ./compiler/lua54.can:324 +local r = "" -- ./compiler/lua54.can:327 +if # vars > 0 then -- ./compiler/lua54.can:328 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 +t[2], -- ./compiler/lua54.can:329 +vars[1], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Op", -- ./compiler/lua54.can:329 +t[4], -- ./compiler/lua54.can:329 +{ -- ./compiler/lua54.can:329 +["tag"] = "Paren", -- ./compiler/lua54.can:329 +values[1] -- ./compiler/lua54.can:329 +}, -- ./compiler/lua54.can:329 +vars[1] -- ./compiler/lua54.can:329 } -- ./compiler/lua54.can:329 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:330 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:329 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +t[2], -- ./compiler/lua54.can:331 +vars[i], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Op", -- ./compiler/lua54.can:331 +t[4], -- ./compiler/lua54.can:331 +{ -- ./compiler/lua54.can:331 +["tag"] = "Paren", -- ./compiler/lua54.can:331 +values[i] -- ./compiler/lua54.can:331 +}, -- ./compiler/lua54.can:331 +vars[i] -- ./compiler/lua54.can:331 +} -- ./compiler/lua54.can:331 +}, "Op")) -- ./compiler/lua54.can:331 end -- ./compiler/lua54.can:331 -return r -- ./compiler/lua54.can:333 -end -- ./compiler/lua54.can:333 -end, -- ./compiler/lua54.can:333 -["While"] = function(t) -- ./compiler/lua54.can:337 -local r = "" -- ./compiler/lua54.can:338 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:339 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:340 -if # lets > 0 then -- ./compiler/lua54.can:341 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:342 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:343 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -end -- ./compiler/lua54.can:344 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:347 -if # lets > 0 then -- ./compiler/lua54.can:348 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:349 -end -- ./compiler/lua54.can:349 -if hasContinue then -- ./compiler/lua54.can:351 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:352 -end -- ./compiler/lua54.can:352 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:354 -if hasContinue then -- ./compiler/lua54.can:355 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:356 -end -- ./compiler/lua54.can:356 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:358 -if # lets > 0 then -- ./compiler/lua54.can:359 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:360 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:361 -end -- ./compiler/lua54.can:361 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:363 -end -- ./compiler/lua54.can:363 -return r -- ./compiler/lua54.can:365 -end, -- ./compiler/lua54.can:365 -["Repeat"] = function(t) -- ./compiler/lua54.can:368 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:369 -local r = "repeat" .. indent() -- ./compiler/lua54.can:370 -if hasContinue then -- ./compiler/lua54.can:371 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:372 -end -- ./compiler/lua54.can:372 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:374 -if hasContinue then -- ./compiler/lua54.can:375 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:376 -end -- ./compiler/lua54.can:376 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:378 -return r -- ./compiler/lua54.can:379 -end, -- ./compiler/lua54.can:379 -["If"] = function(t) -- ./compiler/lua54.can:382 -local r = "" -- ./compiler/lua54.can:383 -local toClose = 0 -- ./compiler/lua54.can:384 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:385 -if # lets > 0 then -- ./compiler/lua54.can:386 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:387 -toClose = toClose + (1) -- ./compiler/lua54.can:388 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:389 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -end -- ./compiler/lua54.can:390 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:393 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:394 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:395 -if # lets > 0 then -- ./compiler/lua54.can:396 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:397 -toClose = toClose + (1) -- ./compiler/lua54.can:398 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:399 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:400 -end -- ./compiler/lua54.can:400 -else -- ./compiler/lua54.can:400 -r = r .. ("else") -- ./compiler/lua54.can:403 -end -- ./compiler/lua54.can:403 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:405 -end -- ./compiler/lua54.can:405 -if # t % 2 == 1 then -- ./compiler/lua54.can:407 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:408 -end -- ./compiler/lua54.can:408 -r = r .. ("end") -- ./compiler/lua54.can:410 -for i = 1, toClose do -- ./compiler/lua54.can:411 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:412 -end -- ./compiler/lua54.can:412 -return r -- ./compiler/lua54.can:414 -end, -- ./compiler/lua54.can:414 -["Fornum"] = function(t) -- ./compiler/lua54.can:417 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:418 -if # t == 5 then -- ./compiler/lua54.can:419 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:420 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:421 -if hasContinue then -- ./compiler/lua54.can:422 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:423 -end -- ./compiler/lua54.can:423 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:425 -if hasContinue then -- ./compiler/lua54.can:426 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:427 -end -- ./compiler/lua54.can:427 -return r .. unindent() .. "end" -- ./compiler/lua54.can:429 -else -- ./compiler/lua54.can:429 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:431 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:432 -if hasContinue then -- ./compiler/lua54.can:433 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:434 -end -- ./compiler/lua54.can:434 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:436 -if hasContinue then -- ./compiler/lua54.can:437 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:438 -end -- ./compiler/lua54.can:438 -return r .. unindent() .. "end" -- ./compiler/lua54.can:440 +end -- ./compiler/lua54.can:331 +if # destructuringVars > 0 then -- ./compiler/lua54.can:334 +local destructured = { -- ./compiler/lua54.can:335 +["rightOp"] = t[2], -- ./compiler/lua54.can:335 +["leftOp"] = t[4] -- ./compiler/lua54.can:335 +} -- ./compiler/lua54.can:335 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 +end -- ./compiler/lua54.can:337 +return r -- ./compiler/lua54.can:339 +end -- ./compiler/lua54.can:339 +end, -- ./compiler/lua54.can:339 +["While"] = function(t) -- ./compiler/lua54.can:343 +local r = "" -- ./compiler/lua54.can:344 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 +if # lets > 0 then -- ./compiler/lua54.can:347 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +end -- ./compiler/lua54.can:350 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 +if # lets > 0 then -- ./compiler/lua54.can:354 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 +end -- ./compiler/lua54.can:355 +if hasContinue then -- ./compiler/lua54.can:357 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 +end -- ./compiler/lua54.can:358 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 +if hasContinue then -- ./compiler/lua54.can:361 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 +end -- ./compiler/lua54.can:362 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 +if # lets > 0 then -- ./compiler/lua54.can:365 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 +end -- ./compiler/lua54.can:367 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +end -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:371 +end, -- ./compiler/lua54.can:371 +["Repeat"] = function(t) -- ./compiler/lua54.can:374 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 +local r = "repeat" .. indent() -- ./compiler/lua54.can:376 +if hasContinue then -- ./compiler/lua54.can:377 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 +end -- ./compiler/lua54.can:378 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 +if hasContinue then -- ./compiler/lua54.can:381 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 +end -- ./compiler/lua54.can:382 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 +return r -- ./compiler/lua54.can:385 +end, -- ./compiler/lua54.can:385 +["If"] = function(t) -- ./compiler/lua54.can:388 +local r = "" -- ./compiler/lua54.can:389 +local toClose = 0 -- ./compiler/lua54.can:390 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 +if # lets > 0 then -- ./compiler/lua54.can:392 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 +toClose = toClose + (1) -- ./compiler/lua54.can:394 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +end -- ./compiler/lua54.can:396 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 +if # lets > 0 then -- ./compiler/lua54.can:402 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 +toClose = toClose + (1) -- ./compiler/lua54.can:404 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 +end -- ./compiler/lua54.can:406 +else -- ./compiler/lua54.can:406 +r = r .. ("else") -- ./compiler/lua54.can:409 +end -- ./compiler/lua54.can:409 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +end -- ./compiler/lua54.can:411 +if # t % 2 == 1 then -- ./compiler/lua54.can:413 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 +end -- ./compiler/lua54.can:414 +r = r .. ("end") -- ./compiler/lua54.can:416 +for i = 1, toClose do -- ./compiler/lua54.can:417 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 +end -- ./compiler/lua54.can:418 +return r -- ./compiler/lua54.can:420 +end, -- ./compiler/lua54.can:420 +["Fornum"] = function(t) -- ./compiler/lua54.can:423 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 +if # t == 5 then -- ./compiler/lua54.can:425 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 +if hasContinue then -- ./compiler/lua54.can:428 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 +end -- ./compiler/lua54.can:429 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 +if hasContinue then -- ./compiler/lua54.can:432 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 +end -- ./compiler/lua54.can:433 +return r .. unindent() .. "end" -- ./compiler/lua54.can:435 +else -- ./compiler/lua54.can:435 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 +if hasContinue then -- ./compiler/lua54.can:439 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 end -- ./compiler/lua54.can:440 -end, -- ./compiler/lua54.can:440 -["Forin"] = function(t) -- ./compiler/lua54.can:444 -local destructured = {} -- ./compiler/lua54.can:445 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:446 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:447 -if hasContinue then -- ./compiler/lua54.can:448 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:449 -end -- ./compiler/lua54.can:449 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:451 -if hasContinue then -- ./compiler/lua54.can:452 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:453 -end -- ./compiler/lua54.can:453 -return r .. unindent() .. "end" -- ./compiler/lua54.can:455 -end, -- ./compiler/lua54.can:455 -["Local"] = function(t) -- ./compiler/lua54.can:458 -local destructured = {} -- ./compiler/lua54.can:459 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:460 -if t[2][1] then -- ./compiler/lua54.can:461 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:462 -end -- ./compiler/lua54.can:462 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:464 -end, -- ./compiler/lua54.can:464 -["Let"] = function(t) -- ./compiler/lua54.can:467 -local destructured = {} -- ./compiler/lua54.can:468 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:469 -local r = "local " .. nameList -- ./compiler/lua54.can:470 -if t[2][1] then -- ./compiler/lua54.can:471 -if all(t[2], { -- ./compiler/lua54.can:472 -"Nil", -- ./compiler/lua54.can:472 -"Dots", -- ./compiler/lua54.can:472 -"Boolean", -- ./compiler/lua54.can:472 -"Number", -- ./compiler/lua54.can:472 -"String" -- ./compiler/lua54.can:472 -}) then -- ./compiler/lua54.can:472 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:473 -else -- ./compiler/lua54.can:473 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -end -- ./compiler/lua54.can:475 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:478 -end, -- ./compiler/lua54.can:478 -["Localrec"] = function(t) -- ./compiler/lua54.can:481 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:482 -end, -- ./compiler/lua54.can:482 -["Goto"] = function(t) -- ./compiler/lua54.can:485 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:486 -end, -- ./compiler/lua54.can:486 -["Label"] = function(t) -- ./compiler/lua54.can:489 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:490 -end, -- ./compiler/lua54.can:490 -["Return"] = function(t) -- ./compiler/lua54.can:493 -local push = peek("push") -- ./compiler/lua54.can:494 -if push then -- ./compiler/lua54.can:495 -local r = "" -- ./compiler/lua54.can:496 -for _, val in ipairs(t) do -- ./compiler/lua54.can:497 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:498 -end -- ./compiler/lua54.can:498 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:500 -else -- ./compiler/lua54.can:500 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:502 -end -- ./compiler/lua54.can:502 -end, -- ./compiler/lua54.can:502 -["Push"] = function(t) -- ./compiler/lua54.can:506 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:507 -r = "" -- ./compiler/lua54.can:508 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:509 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:510 -end -- ./compiler/lua54.can:510 -if t[# t] then -- ./compiler/lua54.can:512 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:513 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:514 -else -- ./compiler/lua54.can:514 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:516 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 +if hasContinue then -- ./compiler/lua54.can:443 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 +end -- ./compiler/lua54.can:444 +return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +end -- ./compiler/lua54.can:446 +end, -- ./compiler/lua54.can:446 +["Forin"] = function(t) -- ./compiler/lua54.can:450 +local destructured = {} -- ./compiler/lua54.can:451 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 +if hasContinue then -- ./compiler/lua54.can:454 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 +end -- ./compiler/lua54.can:455 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 +if hasContinue then -- ./compiler/lua54.can:458 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 +end -- ./compiler/lua54.can:459 +return r .. unindent() .. "end" -- ./compiler/lua54.can:461 +end, -- ./compiler/lua54.can:461 +["Local"] = function(t) -- ./compiler/lua54.can:464 +local destructured = {} -- ./compiler/lua54.can:465 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 +if t[2][1] then -- ./compiler/lua54.can:467 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 +end -- ./compiler/lua54.can:468 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 +end, -- ./compiler/lua54.can:470 +["Let"] = function(t) -- ./compiler/lua54.can:473 +local destructured = {} -- ./compiler/lua54.can:474 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 +local r = "local " .. nameList -- ./compiler/lua54.can:476 +if t[2][1] then -- ./compiler/lua54.can:477 +if all(t[2], { -- ./compiler/lua54.can:478 +"Nil", -- ./compiler/lua54.can:478 +"Dots", -- ./compiler/lua54.can:478 +"Boolean", -- ./compiler/lua54.can:478 +"Number", -- ./compiler/lua54.can:478 +"String" -- ./compiler/lua54.can:478 +}) then -- ./compiler/lua54.can:478 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 +else -- ./compiler/lua54.can:479 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +end -- ./compiler/lua54.can:481 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 +end, -- ./compiler/lua54.can:484 +["Localrec"] = function(t) -- ./compiler/lua54.can:487 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 +end, -- ./compiler/lua54.can:488 +["Goto"] = function(t) -- ./compiler/lua54.can:491 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 +end, -- ./compiler/lua54.can:492 +["Label"] = function(t) -- ./compiler/lua54.can:495 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 +end, -- ./compiler/lua54.can:496 +["Return"] = function(t) -- ./compiler/lua54.can:499 +local push = peek("push") -- ./compiler/lua54.can:500 +if push then -- ./compiler/lua54.can:501 +local r = "" -- ./compiler/lua54.can:502 +for _, val in ipairs(t) do -- ./compiler/lua54.can:503 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 +end -- ./compiler/lua54.can:504 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 +else -- ./compiler/lua54.can:506 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 +end -- ./compiler/lua54.can:508 +end, -- ./compiler/lua54.can:508 +["Push"] = function(t) -- ./compiler/lua54.can:512 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 +r = "" -- ./compiler/lua54.can:514 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 end -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -return r -- ./compiler/lua54.can:519 -end, -- ./compiler/lua54.can:519 -["Break"] = function() -- ./compiler/lua54.can:522 -return "break" -- ./compiler/lua54.can:523 -end, -- ./compiler/lua54.can:523 -["Continue"] = function() -- ./compiler/lua54.can:526 -return "goto " .. var("continue") -- ./compiler/lua54.can:527 -end, -- ./compiler/lua54.can:527 -["Nil"] = function() -- ./compiler/lua54.can:534 -return "nil" -- ./compiler/lua54.can:535 -end, -- ./compiler/lua54.can:535 -["Dots"] = function() -- ./compiler/lua54.can:538 -return "..." -- ./compiler/lua54.can:539 -end, -- ./compiler/lua54.can:539 -["Boolean"] = function(t) -- ./compiler/lua54.can:542 -return tostring(t[1]) -- ./compiler/lua54.can:543 -end, -- ./compiler/lua54.can:543 -["Number"] = function(t) -- ./compiler/lua54.can:546 -return tostring(t[1]) -- ./compiler/lua54.can:547 -end, -- ./compiler/lua54.can:547 -["String"] = function(t) -- ./compiler/lua54.can:550 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:551 -end, -- ./compiler/lua54.can:551 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:554 -local r = "(" -- ./compiler/lua54.can:555 -local decl = {} -- ./compiler/lua54.can:556 -if t[1][1] then -- ./compiler/lua54.can:557 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:558 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:559 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:560 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:561 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:562 -r = r .. (id) -- ./compiler/lua54.can:563 -else -- ./compiler/lua54.can:563 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:565 -end -- ./compiler/lua54.can:565 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:567 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:568 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:569 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:570 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:571 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:572 -r = r .. (", " .. id) -- ./compiler/lua54.can:573 -else -- ./compiler/lua54.can:573 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -end -- ./compiler/lua54.can:575 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:579 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:580 -r = r .. (d .. newline()) -- ./compiler/lua54.can:581 -end -- ./compiler/lua54.can:581 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:583 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:584 -end -- ./compiler/lua54.can:584 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:586 -if hasPush then -- ./compiler/lua54.can:587 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:588 -else -- ./compiler/lua54.can:588 -push("push", false) -- ./compiler/lua54.can:590 -end -- ./compiler/lua54.can:590 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:592 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:593 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:594 -end -- ./compiler/lua54.can:594 -pop("push") -- ./compiler/lua54.can:596 -return r .. unindent() .. "end" -- ./compiler/lua54.can:597 -end, -- ./compiler/lua54.can:597 -["Function"] = function(t) -- ./compiler/lua54.can:599 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:600 -end, -- ./compiler/lua54.can:600 -["Pair"] = function(t) -- ./compiler/lua54.can:603 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:604 -end, -- ./compiler/lua54.can:604 -["Table"] = function(t) -- ./compiler/lua54.can:606 -if # t == 0 then -- ./compiler/lua54.can:607 -return "{}" -- ./compiler/lua54.can:608 -elseif # t == 1 then -- ./compiler/lua54.can:609 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:610 -else -- ./compiler/lua54.can:610 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:612 -end -- ./compiler/lua54.can:612 -end, -- ./compiler/lua54.can:612 -["TableCompr"] = function(t) -- ./compiler/lua54.can:616 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:617 -end, -- ./compiler/lua54.can:617 -["Op"] = function(t) -- ./compiler/lua54.can:620 -local r -- ./compiler/lua54.can:621 -if # t == 2 then -- ./compiler/lua54.can:622 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:623 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:624 +if t[# t] then -- ./compiler/lua54.can:518 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 +else -- ./compiler/lua54.can:520 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +end -- ./compiler/lua54.can:522 +return r -- ./compiler/lua54.can:525 +end, -- ./compiler/lua54.can:525 +["Break"] = function() -- ./compiler/lua54.can:528 +return "break" -- ./compiler/lua54.can:529 +end, -- ./compiler/lua54.can:529 +["Continue"] = function() -- ./compiler/lua54.can:532 +return "goto " .. var("continue") -- ./compiler/lua54.can:533 +end, -- ./compiler/lua54.can:533 +["Nil"] = function() -- ./compiler/lua54.can:540 +return "nil" -- ./compiler/lua54.can:541 +end, -- ./compiler/lua54.can:541 +["Dots"] = function() -- ./compiler/lua54.can:544 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 +return r -- ./compiler/lua54.can:550 +else -- ./compiler/lua54.can:550 +return "..." -- ./compiler/lua54.can:552 +end -- ./compiler/lua54.can:552 +end, -- ./compiler/lua54.can:552 +["Boolean"] = function(t) -- ./compiler/lua54.can:556 +return tostring(t[1]) -- ./compiler/lua54.can:557 +end, -- ./compiler/lua54.can:557 +["Number"] = function(t) -- ./compiler/lua54.can:560 +return tostring(t[1]) -- ./compiler/lua54.can:561 +end, -- ./compiler/lua54.can:561 +["String"] = function(t) -- ./compiler/lua54.can:564 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 +end, -- ./compiler/lua54.can:565 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 +local r = "(" -- ./compiler/lua54.can:569 +local decl = {} -- ./compiler/lua54.can:570 +if t[1][1] then -- ./compiler/lua54.can:571 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 +r = r .. (id) -- ./compiler/lua54.can:577 +else -- ./compiler/lua54.can:577 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 +end -- ./compiler/lua54.can:579 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 +r = r .. (", " .. id) -- ./compiler/lua54.can:587 +else -- ./compiler/lua54.can:587 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +end -- ./compiler/lua54.can:589 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 +r = r .. (d .. newline()) -- ./compiler/lua54.can:595 +end -- ./compiler/lua54.can:595 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 +end -- ./compiler/lua54.can:598 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 +if hasPush then -- ./compiler/lua54.can:601 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 +else -- ./compiler/lua54.can:602 +push("push", false) -- ./compiler/lua54.can:604 +end -- ./compiler/lua54.can:604 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 +end -- ./compiler/lua54.can:608 +pop("push") -- ./compiler/lua54.can:610 +return r .. unindent() .. "end" -- ./compiler/lua54.can:611 +end, -- ./compiler/lua54.can:611 +["Function"] = function(t) -- ./compiler/lua54.can:613 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 +end, -- ./compiler/lua54.can:614 +["Pair"] = function(t) -- ./compiler/lua54.can:617 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 +end, -- ./compiler/lua54.can:618 +["Table"] = function(t) -- ./compiler/lua54.can:620 +if # t == 0 then -- ./compiler/lua54.can:621 +return "{}" -- ./compiler/lua54.can:622 +elseif # t == 1 then -- ./compiler/lua54.can:623 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 else -- ./compiler/lua54.can:624 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 end -- ./compiler/lua54.can:626 -else -- ./compiler/lua54.can:626 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:629 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:630 -else -- ./compiler/lua54.can:630 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -end -- ./compiler/lua54.can:632 -return r -- ./compiler/lua54.can:635 -end, -- ./compiler/lua54.can:635 -["Paren"] = function(t) -- ./compiler/lua54.can:638 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:639 -end, -- ./compiler/lua54.can:639 -["MethodStub"] = function(t) -- ./compiler/lua54.can:642 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:648 -end, -- ./compiler/lua54.can:648 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:651 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:658 -end, -- ./compiler/lua54.can:658 -["LetExpr"] = function(t) -- ./compiler/lua54.can:665 -return lua(t[1][1]) -- ./compiler/lua54.can:666 -end, -- ./compiler/lua54.can:666 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:670 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:671 -local r = "(function()" .. indent() -- ./compiler/lua54.can:672 -if hasPush then -- ./compiler/lua54.can:673 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:674 -else -- ./compiler/lua54.can:674 -push("push", false) -- ./compiler/lua54.can:676 -end -- ./compiler/lua54.can:676 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:678 -if hasPush then -- ./compiler/lua54.can:679 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:680 -end -- ./compiler/lua54.can:680 -pop("push") -- ./compiler/lua54.can:682 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:683 -return r -- ./compiler/lua54.can:684 -end, -- ./compiler/lua54.can:684 -["DoExpr"] = function(t) -- ./compiler/lua54.can:687 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:688 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:689 -end -- ./compiler/lua54.can:689 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:691 -end, -- ./compiler/lua54.can:691 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:694 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:695 -end, -- ./compiler/lua54.can:695 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:698 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:699 -end, -- ./compiler/lua54.can:699 -["IfExpr"] = function(t) -- ./compiler/lua54.can:702 -for i = 2, # t do -- ./compiler/lua54.can:703 -local block = t[i] -- ./compiler/lua54.can:704 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:705 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -end -- ./compiler/lua54.can:706 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:709 +end, -- ./compiler/lua54.can:626 +["TableCompr"] = function(t) -- ./compiler/lua54.can:630 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 +end, -- ./compiler/lua54.can:631 +["Op"] = function(t) -- ./compiler/lua54.can:634 +local r -- ./compiler/lua54.can:635 +if # t == 2 then -- ./compiler/lua54.can:636 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 +else -- ./compiler/lua54.can:638 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 +end -- ./compiler/lua54.can:640 +else -- ./compiler/lua54.can:640 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 +else -- ./compiler/lua54.can:644 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +end -- ./compiler/lua54.can:646 +return r -- ./compiler/lua54.can:649 +end, -- ./compiler/lua54.can:649 +["Paren"] = function(t) -- ./compiler/lua54.can:652 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 +end, -- ./compiler/lua54.can:653 +["MethodStub"] = function(t) -- ./compiler/lua54.can:656 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 +end, -- ./compiler/lua54.can:662 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 +end, -- ./compiler/lua54.can:672 +["LetExpr"] = function(t) -- ./compiler/lua54.can:679 +return lua(t[1][1]) -- ./compiler/lua54.can:680 +end, -- ./compiler/lua54.can:680 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 +local r = "(function()" .. indent() -- ./compiler/lua54.can:686 +if hasPush then -- ./compiler/lua54.can:687 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 +else -- ./compiler/lua54.can:688 +push("push", false) -- ./compiler/lua54.can:690 +end -- ./compiler/lua54.can:690 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 +if hasPush then -- ./compiler/lua54.can:693 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 +end -- ./compiler/lua54.can:694 +pop("push") -- ./compiler/lua54.can:696 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 +return r -- ./compiler/lua54.can:698 +end, -- ./compiler/lua54.can:698 +["DoExpr"] = function(t) -- ./compiler/lua54.can:701 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 +end -- ./compiler/lua54.can:703 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 +end, -- ./compiler/lua54.can:705 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 end, -- ./compiler/lua54.can:709 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:713 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 end, -- ./compiler/lua54.can:713 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:716 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:717 -end, -- ./compiler/lua54.can:717 -["Call"] = function(t) -- ./compiler/lua54.can:723 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:724 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:725 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:726 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:727 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:728 -else -- ./compiler/lua54.can:728 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:730 -end -- ./compiler/lua54.can:730 -else -- ./compiler/lua54.can:730 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:733 -end -- ./compiler/lua54.can:733 -end, -- ./compiler/lua54.can:733 -["SafeCall"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:738 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:739 -else -- ./compiler/lua54.can:739 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:741 -end -- ./compiler/lua54.can:741 -end, -- ./compiler/lua54.can:741 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:746 -if start == nil then start = 1 end -- ./compiler/lua54.can:746 -local r -- ./compiler/lua54.can:747 -if t[start] then -- ./compiler/lua54.can:748 -r = lua(t[start]) -- ./compiler/lua54.can:749 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:750 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:751 -end -- ./compiler/lua54.can:751 +["IfExpr"] = function(t) -- ./compiler/lua54.can:716 +for i = 2, # t do -- ./compiler/lua54.can:717 +local block = t[i] -- ./compiler/lua54.can:718 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +end -- ./compiler/lua54.can:720 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 +end, -- ./compiler/lua54.can:723 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 +end, -- ./compiler/lua54.can:727 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 +end, -- ./compiler/lua54.can:731 +["Call"] = function(t) -- ./compiler/lua54.can:737 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 +local replacement = macro["replacement"] -- ./compiler/lua54.can:742 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 +macroargs["..."] = (function() -- ./compiler/lua54.can:746 +local self = {} -- ./compiler/lua54.can:746 +for j = i + 1, # t do -- ./compiler/lua54.can:746 +self[#self+1] = t[j] -- ./compiler/lua54.can:746 +end -- ./compiler/lua54.can:746 +return self -- ./compiler/lua54.can:746 +end)() -- ./compiler/lua54.can:746 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 +if t[i + 1] == nil then -- ./compiler/lua54.can:748 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 +end -- ./compiler/lua54.can:749 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 else -- ./compiler/lua54.can:751 -r = "" -- ./compiler/lua54.can:754 -end -- ./compiler/lua54.can:754 -return r -- ./compiler/lua54.can:756 -end, -- ./compiler/lua54.can:756 -["Id"] = function(t) -- ./compiler/lua54.can:759 -return t[1] -- ./compiler/lua54.can:760 -end, -- ./compiler/lua54.can:760 -["AttributeId"] = function(t) -- ./compiler/lua54.can:763 -if t[2] then -- ./compiler/lua54.can:764 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:765 -else -- ./compiler/lua54.can:765 -return t[1] -- ./compiler/lua54.can:767 -end -- ./compiler/lua54.can:767 -end, -- ./compiler/lua54.can:767 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:771 -if t["id"] then -- ./compiler/lua54.can:772 -return t["id"] -- ./compiler/lua54.can:773 -else -- ./compiler/lua54.can:773 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:775 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:776 -for j = 1, # t, 1 do -- ./compiler/lua54.can:777 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:778 -end -- ./compiler/lua54.can:778 -table["insert"](d, vars) -- ./compiler/lua54.can:780 -t["id"] = vars["id"] -- ./compiler/lua54.can:781 -return vars["id"] -- ./compiler/lua54.can:782 -end -- ./compiler/lua54.can:782 -end, -- ./compiler/lua54.can:782 -["Index"] = function(t) -- ./compiler/lua54.can:786 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:787 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:788 -else -- ./compiler/lua54.can:788 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:790 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +end -- ./compiler/lua54.can:753 +push("macroargs", macroargs) -- ./compiler/lua54.can:756 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 +local r = lua(replacement) -- ./compiler/lua54.can:758 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 +pop("macroargs") -- ./compiler/lua54.can:760 +return r -- ./compiler/lua54.can:761 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 +else -- ./compiler/lua54.can:764 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 +end -- ./compiler/lua54.can:766 +else -- ./compiler/lua54.can:766 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +end -- ./compiler/lua54.can:769 +end, -- ./compiler/lua54.can:769 +["SafeCall"] = function(t) -- ./compiler/lua54.can:773 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +else -- ./compiler/lua54.can:775 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +end -- ./compiler/lua54.can:777 +end, -- ./compiler/lua54.can:777 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 +if start == nil then start = 1 end -- ./compiler/lua54.can:782 +local r -- ./compiler/lua54.can:783 +if t[start] then -- ./compiler/lua54.can:784 +r = lua(t[start]) -- ./compiler/lua54.can:785 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 +end -- ./compiler/lua54.can:787 +else -- ./compiler/lua54.can:787 +r = "" -- ./compiler/lua54.can:790 end -- ./compiler/lua54.can:790 -end, -- ./compiler/lua54.can:790 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:794 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:795 -local l = {} -- ./compiler/lua54.can:796 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:797 -table["insert"](l, 1, t) -- ./compiler/lua54.can:798 -t = t[1] -- ./compiler/lua54.can:799 -end -- ./compiler/lua54.can:799 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:801 -for _, e in ipairs(l) do -- ./compiler/lua54.can:802 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:803 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:804 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:805 -else -- ./compiler/lua54.can:805 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:807 +return r -- ./compiler/lua54.can:792 +end, -- ./compiler/lua54.can:792 +["Id"] = function(t) -- ./compiler/lua54.can:795 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 +local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:802 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 +local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 +return r -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 end -- ./compiler/lua54.can:807 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:810 -return r -- ./compiler/lua54.can:811 -else -- ./compiler/lua54.can:811 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:813 -end -- ./compiler/lua54.can:813 -end, -- ./compiler/lua54.can:813 -["_opid"] = { -- ./compiler/lua54.can:818 -["add"] = "+", -- ./compiler/lua54.can:819 -["sub"] = "-", -- ./compiler/lua54.can:819 -["mul"] = "*", -- ./compiler/lua54.can:819 -["div"] = "/", -- ./compiler/lua54.can:819 -["idiv"] = "//", -- ./compiler/lua54.can:820 -["mod"] = "%", -- ./compiler/lua54.can:820 -["pow"] = "^", -- ./compiler/lua54.can:820 -["concat"] = "..", -- ./compiler/lua54.can:820 -["band"] = "&", -- ./compiler/lua54.can:821 -["bor"] = "|", -- ./compiler/lua54.can:821 -["bxor"] = "~", -- ./compiler/lua54.can:821 -["shl"] = "<<", -- ./compiler/lua54.can:821 -["shr"] = ">>", -- ./compiler/lua54.can:821 -["eq"] = "==", -- ./compiler/lua54.can:822 -["ne"] = "~=", -- ./compiler/lua54.can:822 -["lt"] = "<", -- ./compiler/lua54.can:822 -["gt"] = ">", -- ./compiler/lua54.can:822 -["le"] = "<=", -- ./compiler/lua54.can:822 -["ge"] = ">=", -- ./compiler/lua54.can:822 -["and"] = "and", -- ./compiler/lua54.can:823 -["or"] = "or", -- ./compiler/lua54.can:823 -["unm"] = "-", -- ./compiler/lua54.can:823 -["len"] = "#", -- ./compiler/lua54.can:823 -["bnot"] = "~", -- ./compiler/lua54.can:823 -["not"] = "not" -- ./compiler/lua54.can:823 -} -- ./compiler/lua54.can:823 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:826 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:827 -end }) -- ./compiler/lua54.can:827 +return t[1] -- ./compiler/lua54.can:810 +end, -- ./compiler/lua54.can:810 +["AttributeId"] = function(t) -- ./compiler/lua54.can:813 +if t[2] then -- ./compiler/lua54.can:814 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 +else -- ./compiler/lua54.can:815 +return t[1] -- ./compiler/lua54.can:817 +end -- ./compiler/lua54.can:817 +end, -- ./compiler/lua54.can:817 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 +if t["id"] then -- ./compiler/lua54.can:822 +return t["id"] -- ./compiler/lua54.can:823 +else -- ./compiler/lua54.can:823 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 +for j = 1, # t, 1 do -- ./compiler/lua54.can:827 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 +end -- ./compiler/lua54.can:828 +table["insert"](d, vars) -- ./compiler/lua54.can:830 +t["id"] = vars["id"] -- ./compiler/lua54.can:831 +return vars["id"] -- ./compiler/lua54.can:832 +end -- ./compiler/lua54.can:832 +end, -- ./compiler/lua54.can:832 +["Index"] = function(t) -- ./compiler/lua54.can:836 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 +else -- ./compiler/lua54.can:838 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 +end -- ./compiler/lua54.can:840 +end, -- ./compiler/lua54.can:840 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 +local l = {} -- ./compiler/lua54.can:846 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 +table["insert"](l, 1, t) -- ./compiler/lua54.can:848 +t = t[1] -- ./compiler/lua54.can:849 +end -- ./compiler/lua54.can:849 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 +for _, e in ipairs(l) do -- ./compiler/lua54.can:852 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 +else -- ./compiler/lua54.can:855 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +end -- ./compiler/lua54.can:857 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 +return r -- ./compiler/lua54.can:861 +else -- ./compiler/lua54.can:861 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 +end -- ./compiler/lua54.can:863 +end, -- ./compiler/lua54.can:863 +["_opid"] = { -- ./compiler/lua54.can:868 +["add"] = "+", -- ./compiler/lua54.can:869 +["sub"] = "-", -- ./compiler/lua54.can:869 +["mul"] = "*", -- ./compiler/lua54.can:869 +["div"] = "/", -- ./compiler/lua54.can:869 +["idiv"] = "//", -- ./compiler/lua54.can:870 +["mod"] = "%", -- ./compiler/lua54.can:870 +["pow"] = "^", -- ./compiler/lua54.can:870 +["concat"] = "..", -- ./compiler/lua54.can:870 +["band"] = "&", -- ./compiler/lua54.can:871 +["bor"] = "|", -- ./compiler/lua54.can:871 +["bxor"] = "~", -- ./compiler/lua54.can:871 +["shl"] = "<<", -- ./compiler/lua54.can:871 +["shr"] = ">>", -- ./compiler/lua54.can:871 +["eq"] = "==", -- ./compiler/lua54.can:872 +["ne"] = "~=", -- ./compiler/lua54.can:872 +["lt"] = "<", -- ./compiler/lua54.can:872 +["gt"] = ">", -- ./compiler/lua54.can:872 +["le"] = "<=", -- ./compiler/lua54.can:872 +["ge"] = ">=", -- ./compiler/lua54.can:872 +["and"] = "and", -- ./compiler/lua54.can:873 +["or"] = "or", -- ./compiler/lua54.can:873 +["unm"] = "-", -- ./compiler/lua54.can:873 +["len"] = "#", -- ./compiler/lua54.can:873 +["bnot"] = "~", -- ./compiler/lua54.can:873 +["not"] = "not" -- ./compiler/lua54.can:873 +} -- ./compiler/lua54.can:873 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 +end }) -- ./compiler/lua54.can:877 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -4648,11 +4961,11 @@ end -- ./compiler/lua51.can:26 tags["Label"] = function() -- ./compiler/lua51.can:28 error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 end -- ./compiler/lua51.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:833 -return requireStr .. code -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -end -- ./compiler/lua54.can:834 -local lua54 = _() or lua54 -- ./compiler/lua54.can:839 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 +return requireStr .. code -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +end -- ./compiler/lua54.can:884 +local lua54 = _() or lua54 -- ./compiler/lua54.can:889 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -6060,343 +6373,370 @@ end -- ./candran/can-parser/parser.lua:303 t["is_short"] = true -- ./candran/can-parser/parser.lua:305 return t -- ./candran/can-parser/parser.lua:306 end -- ./candran/can-parser/parser.lua:306 -local function statToExpr(t) -- ./candran/can-parser/parser.lua:309 -t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:310 +local function markImplicit(t) -- ./candran/can-parser/parser.lua:309 +t["implicit"] = true -- ./candran/can-parser/parser.lua:310 return t -- ./candran/can-parser/parser.lua:311 end -- ./candran/can-parser/parser.lua:311 -local function fixStructure(t) -- ./candran/can-parser/parser.lua:314 -local i = 1 -- ./candran/can-parser/parser.lua:315 -while i <= # t do -- ./candran/can-parser/parser.lua:316 -if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:317 -fixStructure(t[i]) -- ./candran/can-parser/parser.lua:318 -for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:319 -local stat = t[i][j] -- ./candran/can-parser/parser.lua:320 -if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:321 -table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:322 -table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:323 -if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:324 -stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:325 -end -- ./candran/can-parser/parser.lua:325 -end -- ./candran/can-parser/parser.lua:325 -end -- ./candran/can-parser/parser.lua:325 -end -- ./candran/can-parser/parser.lua:325 -i = i + 1 -- ./candran/can-parser/parser.lua:330 +local function statToExpr(t) -- ./candran/can-parser/parser.lua:314 +t["tag"] = t["tag"] .. "Expr" -- ./candran/can-parser/parser.lua:315 +return t -- ./candran/can-parser/parser.lua:316 +end -- ./candran/can-parser/parser.lua:316 +local function fixStructure(t) -- ./candran/can-parser/parser.lua:319 +local i = 1 -- ./candran/can-parser/parser.lua:320 +while i <= # t do -- ./candran/can-parser/parser.lua:321 +if type(t[i]) == "table" then -- ./candran/can-parser/parser.lua:322 +fixStructure(t[i]) -- ./candran/can-parser/parser.lua:323 +for j = # t[i], 1, - 1 do -- ./candran/can-parser/parser.lua:324 +local stat = t[i][j] -- ./candran/can-parser/parser.lua:325 +if type(stat) == "table" and stat["move_up_block"] and stat["move_up_block"] > 0 then -- ./candran/can-parser/parser.lua:326 +table["remove"](t[i], j) -- ./candran/can-parser/parser.lua:327 +table["insert"](t, i + 1, stat) -- ./candran/can-parser/parser.lua:328 +if t["tag"] == "Block" or t["tag"] == "Do" then -- ./candran/can-parser/parser.lua:329 +stat["move_up_block"] = stat["move_up_block"] - 1 -- ./candran/can-parser/parser.lua:330 end -- ./candran/can-parser/parser.lua:330 -return t -- ./candran/can-parser/parser.lua:332 -end -- ./candran/can-parser/parser.lua:332 -local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:335 -for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:336 -if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:338 -local exprlist -- ./candran/can-parser/parser.lua:339 -if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:341 -exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:342 -elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:343 -exprlist = stat -- ./candran/can-parser/parser.lua:344 -end -- ./candran/can-parser/parser.lua:344 -local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:347 -if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:351 -local p = i -- ./candran/can-parser/parser.lua:352 -for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:353 -p = i + j -- ./candran/can-parser/parser.lua:354 -table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:355 -if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:357 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:358 -end -- ./candran/can-parser/parser.lua:358 -if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:361 -fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:362 -end -- ./candran/can-parser/parser.lua:362 -end -- ./candran/can-parser/parser.lua:362 -exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:366 -exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:367 -if not isRecCall then -- ./candran/can-parser/parser.lua:369 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:370 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:371 -end -- ./candran/can-parser/parser.lua:371 -end -- ./candran/can-parser/parser.lua:371 -return block, i -- ./candran/can-parser/parser.lua:375 -elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:378 -local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:379 -if r then -- ./candran/can-parser/parser.lua:380 -for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:381 -table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:382 -end -- ./candran/can-parser/parser.lua:382 -return block, i -- ./candran/can-parser/parser.lua:384 -end -- ./candran/can-parser/parser.lua:384 -elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:386 -local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:387 -if r then -- ./candran/can-parser/parser.lua:388 +end -- ./candran/can-parser/parser.lua:330 +end -- ./candran/can-parser/parser.lua:330 +end -- ./candran/can-parser/parser.lua:330 +i = i + 1 -- ./candran/can-parser/parser.lua:335 +end -- ./candran/can-parser/parser.lua:335 +return t -- ./candran/can-parser/parser.lua:337 +end -- ./candran/can-parser/parser.lua:337 +local function searchEndRec(block, isRecCall) -- ./candran/can-parser/parser.lua:340 +for i, stat in ipairs(block) do -- ./candran/can-parser/parser.lua:341 +if stat["tag"] == "Set" or stat["tag"] == "Push" or stat["tag"] == "Return" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:343 +local exprlist -- ./candran/can-parser/parser.lua:344 +if stat["tag"] == "Set" or stat["tag"] == "Local" or stat["tag"] == "Let" or stat["tag"] == "Localrec" then -- ./candran/can-parser/parser.lua:346 +exprlist = stat[# stat] -- ./candran/can-parser/parser.lua:347 +elseif stat["tag"] == "Push" or stat["tag"] == "Return" then -- ./candran/can-parser/parser.lua:348 +exprlist = stat -- ./candran/can-parser/parser.lua:349 +end -- ./candran/can-parser/parser.lua:349 +local last = exprlist[# exprlist] -- ./candran/can-parser/parser.lua:352 +if last["tag"] == "Function" and last["is_short"] and not last["is_method"] and # last[1] == 1 then -- ./candran/can-parser/parser.lua:356 +local p = i -- ./candran/can-parser/parser.lua:357 +for j, fstat in ipairs(last[2]) do -- ./candran/can-parser/parser.lua:358 +p = i + j -- ./candran/can-parser/parser.lua:359 +table["insert"](block, p, fstat) -- ./candran/can-parser/parser.lua:360 +if stat["move_up_block"] then -- ./candran/can-parser/parser.lua:362 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + stat["move_up_block"] -- ./candran/can-parser/parser.lua:363 +end -- ./candran/can-parser/parser.lua:363 +if block["is_singlestatblock"] then -- ./candran/can-parser/parser.lua:366 +fstat["move_up_block"] = (fstat["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:367 +end -- ./candran/can-parser/parser.lua:367 +end -- ./candran/can-parser/parser.lua:367 +exprlist[# exprlist] = last[1] -- ./candran/can-parser/parser.lua:371 +exprlist[# exprlist]["tag"] = "Paren" -- ./candran/can-parser/parser.lua:372 +if not isRecCall then -- ./candran/can-parser/parser.lua:374 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:375 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:376 +end -- ./candran/can-parser/parser.lua:376 +end -- ./candran/can-parser/parser.lua:376 +return block, i -- ./candran/can-parser/parser.lua:380 +elseif last["tag"]:match("Expr$") then -- ./candran/can-parser/parser.lua:383 +local r = searchEndRec({ last }) -- ./candran/can-parser/parser.lua:384 +if r then -- ./candran/can-parser/parser.lua:385 +for j = 2, # r, 1 do -- ./candran/can-parser/parser.lua:386 +table["insert"](block, i + j - 1, r[j]) -- ./candran/can-parser/parser.lua:387 +end -- ./candran/can-parser/parser.lua:387 return block, i -- ./candran/can-parser/parser.lua:389 end -- ./candran/can-parser/parser.lua:389 -end -- ./candran/can-parser/parser.lua:389 -elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:394 -local blocks -- ./candran/can-parser/parser.lua:395 -if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:397 -blocks = stat -- ./candran/can-parser/parser.lua:398 -elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:399 -blocks = { stat } -- ./candran/can-parser/parser.lua:400 -end -- ./candran/can-parser/parser.lua:400 -for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:403 -if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:404 -local oldLen = # iblock -- ./candran/can-parser/parser.lua:405 -local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:406 -if newiBlock then -- ./candran/can-parser/parser.lua:407 -local p = i -- ./candran/can-parser/parser.lua:408 -for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:409 -p = p + 1 -- ./candran/can-parser/parser.lua:410 -table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:411 -iblock[j] = nil -- ./candran/can-parser/parser.lua:412 -end -- ./candran/can-parser/parser.lua:412 -if not isRecCall then -- ./candran/can-parser/parser.lua:415 -for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:416 -block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:417 +elseif last["tag"] == "Function" then -- ./candran/can-parser/parser.lua:391 +local r = searchEndRec(last[2]) -- ./candran/can-parser/parser.lua:392 +if r then -- ./candran/can-parser/parser.lua:393 +return block, i -- ./candran/can-parser/parser.lua:394 +end -- ./candran/can-parser/parser.lua:394 +end -- ./candran/can-parser/parser.lua:394 +elseif stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Do") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:399 +local blocks -- ./candran/can-parser/parser.lua:400 +if stat["tag"]:match("^If") or stat["tag"]:match("^While") or stat["tag"]:match("^Repeat") or stat["tag"]:match("^Fornum") or stat["tag"]:match("^Forin") then -- ./candran/can-parser/parser.lua:402 +blocks = stat -- ./candran/can-parser/parser.lua:403 +elseif stat["tag"]:match("^Do") then -- ./candran/can-parser/parser.lua:404 +blocks = { stat } -- ./candran/can-parser/parser.lua:405 +end -- ./candran/can-parser/parser.lua:405 +for _, iblock in ipairs(blocks) do -- ./candran/can-parser/parser.lua:408 +if iblock["tag"] == "Block" then -- ./candran/can-parser/parser.lua:409 +local oldLen = # iblock -- ./candran/can-parser/parser.lua:410 +local newiBlock, newEnd = searchEndRec(iblock, true) -- ./candran/can-parser/parser.lua:411 +if newiBlock then -- ./candran/can-parser/parser.lua:412 +local p = i -- ./candran/can-parser/parser.lua:413 +for j = newEnd + (# iblock - oldLen) + 1, # iblock, 1 do -- ./candran/can-parser/parser.lua:414 +p = p + 1 -- ./candran/can-parser/parser.lua:415 +table["insert"](block, p, iblock[j]) -- ./candran/can-parser/parser.lua:416 +iblock[j] = nil -- ./candran/can-parser/parser.lua:417 end -- ./candran/can-parser/parser.lua:417 -end -- ./candran/can-parser/parser.lua:417 -return block, i -- ./candran/can-parser/parser.lua:421 -end -- ./candran/can-parser/parser.lua:421 -end -- ./candran/can-parser/parser.lua:421 -end -- ./candran/can-parser/parser.lua:421 -end -- ./candran/can-parser/parser.lua:421 -end -- ./candran/can-parser/parser.lua:421 -return nil -- ./candran/can-parser/parser.lua:427 -end -- ./candran/can-parser/parser.lua:427 -local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:430 -local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:431 -if not r then -- ./candran/can-parser/parser.lua:432 -return false -- ./candran/can-parser/parser.lua:433 -end -- ./candran/can-parser/parser.lua:433 -return true, r -- ./candran/can-parser/parser.lua:435 -end -- ./candran/can-parser/parser.lua:435 -local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:438 -if canFollow then -- ./candran/can-parser/parser.lua:439 -return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:442 -else -- ./candran/can-parser/parser.lua:442 -return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:446 -end -- ./candran/can-parser/parser.lua:446 -end -- ./candran/can-parser/parser.lua:446 -local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:450 -return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:452 -end -- ./candran/can-parser/parser.lua:452 -local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:455 -return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:457 +if not isRecCall then -- ./candran/can-parser/parser.lua:420 +for j = p + 1, # block, 1 do -- ./candran/can-parser/parser.lua:421 +block[j]["move_up_block"] = (block[j]["move_up_block"] or 0) + 1 -- ./candran/can-parser/parser.lua:422 +end -- ./candran/can-parser/parser.lua:422 +end -- ./candran/can-parser/parser.lua:422 +return block, i -- ./candran/can-parser/parser.lua:426 +end -- ./candran/can-parser/parser.lua:426 +end -- ./candran/can-parser/parser.lua:426 +end -- ./candran/can-parser/parser.lua:426 +end -- ./candran/can-parser/parser.lua:426 +end -- ./candran/can-parser/parser.lua:426 +return nil -- ./candran/can-parser/parser.lua:432 +end -- ./candran/can-parser/parser.lua:432 +local function searchEnd(s, p, t) -- ./candran/can-parser/parser.lua:435 +local r = searchEndRec(fixStructure(t)) -- ./candran/can-parser/parser.lua:436 +if not r then -- ./candran/can-parser/parser.lua:437 +return false -- ./candran/can-parser/parser.lua:438 +end -- ./candran/can-parser/parser.lua:438 +return true, r -- ./candran/can-parser/parser.lua:440 +end -- ./candran/can-parser/parser.lua:440 +local function expectBlockOrSingleStatWithStartEnd(start, startLabel, stopLabel, canFollow) -- ./candran/can-parser/parser.lua:443 +if canFollow then -- ./candran/can-parser/parser.lua:444 +return (- start * V("SingleStatBlock") * canFollow ^ - 1) + (expect(start, startLabel) * ((V("Block") * (canFollow + kw("end"))) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:447 +else -- ./candran/can-parser/parser.lua:447 +return (- start * V("SingleStatBlock")) + (expect(start, startLabel) * ((V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(stopLabel)))) -- ./candran/can-parser/parser.lua:451 +end -- ./candran/can-parser/parser.lua:451 +end -- ./candran/can-parser/parser.lua:451 +local function expectBlockWithEnd(label) -- ./candran/can-parser/parser.lua:455 +return (V("Block") * kw("end")) + (Cmt(V("Block"), searchEnd) + throw(label)) -- ./candran/can-parser/parser.lua:457 end -- ./candran/can-parser/parser.lua:457 -local function maybe(patt) -- ./candran/can-parser/parser.lua:460 -return # patt / 0 * patt -- ./candran/can-parser/parser.lua:461 -end -- ./candran/can-parser/parser.lua:461 -local function setAttribute(attribute) -- ./candran/can-parser/parser.lua:464 -return function(assign) -- ./candran/can-parser/parser.lua:465 -assign[1]["tag"] = "AttributeNameList" -- ./candran/can-parser/parser.lua:466 -for _, id in ipairs(assign[1]) do -- ./candran/can-parser/parser.lua:467 -if id["tag"] == "Id" then -- ./candran/can-parser/parser.lua:468 -id["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:469 -id[2] = attribute -- ./candran/can-parser/parser.lua:470 -elseif id["tag"] == "DestructuringId" then -- ./candran/can-parser/parser.lua:471 -for _, did in ipairs(id) do -- ./candran/can-parser/parser.lua:472 -did["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:473 -did[2] = attribute -- ./candran/can-parser/parser.lua:474 -end -- ./candran/can-parser/parser.lua:474 -end -- ./candran/can-parser/parser.lua:474 -end -- ./candran/can-parser/parser.lua:474 -return assign -- ./candran/can-parser/parser.lua:478 -end -- ./candran/can-parser/parser.lua:478 -end -- ./candran/can-parser/parser.lua:478 -local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:483 -local function push(f) -- ./candran/can-parser/parser.lua:485 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:486 -table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:487 -return true -- ./candran/can-parser/parser.lua:488 -end) -- ./candran/can-parser/parser.lua:488 -end -- ./candran/can-parser/parser.lua:488 -local function pop(f) -- ./candran/can-parser/parser.lua:491 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:492 -table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:493 -return true -- ./candran/can-parser/parser.lua:494 -end) -- ./candran/can-parser/parser.lua:494 -end -- ./candran/can-parser/parser.lua:494 -local function when(f) -- ./candran/can-parser/parser.lua:497 -return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:498 -return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:499 +local function maybeBlockWithEnd() -- ./candran/can-parser/parser.lua:460 +return (V("BlockNoErr") * kw("end")) + Cmt(V("BlockNoErr"), searchEnd) -- ./candran/can-parser/parser.lua:462 +end -- ./candran/can-parser/parser.lua:462 +local function maybe(patt) -- ./candran/can-parser/parser.lua:465 +return # patt / 0 * patt -- ./candran/can-parser/parser.lua:466 +end -- ./candran/can-parser/parser.lua:466 +local function setAttribute(attribute) -- ./candran/can-parser/parser.lua:469 +return function(assign) -- ./candran/can-parser/parser.lua:470 +assign[1]["tag"] = "AttributeNameList" -- ./candran/can-parser/parser.lua:471 +for _, id in ipairs(assign[1]) do -- ./candran/can-parser/parser.lua:472 +if id["tag"] == "Id" then -- ./candran/can-parser/parser.lua:473 +id["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:474 +id[2] = attribute -- ./candran/can-parser/parser.lua:475 +elseif id["tag"] == "DestructuringId" then -- ./candran/can-parser/parser.lua:476 +for _, did in ipairs(id) do -- ./candran/can-parser/parser.lua:477 +did["tag"] = "AttributeId" -- ./candran/can-parser/parser.lua:478 +did[2] = attribute -- ./candran/can-parser/parser.lua:479 +end -- ./candran/can-parser/parser.lua:479 +end -- ./candran/can-parser/parser.lua:479 +end -- ./candran/can-parser/parser.lua:479 +return assign -- ./candran/can-parser/parser.lua:483 +end -- ./candran/can-parser/parser.lua:483 +end -- ./candran/can-parser/parser.lua:483 +local stacks = { ["lexpr"] = {} } -- ./candran/can-parser/parser.lua:488 +local function push(f) -- ./candran/can-parser/parser.lua:490 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:491 +table["insert"](stacks[f], true) -- ./candran/can-parser/parser.lua:492 +return true -- ./candran/can-parser/parser.lua:493 +end) -- ./candran/can-parser/parser.lua:493 +end -- ./candran/can-parser/parser.lua:493 +local function pop(f) -- ./candran/can-parser/parser.lua:496 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:497 +table["remove"](stacks[f]) -- ./candran/can-parser/parser.lua:498 +return true -- ./candran/can-parser/parser.lua:499 end) -- ./candran/can-parser/parser.lua:499 end -- ./candran/can-parser/parser.lua:499 -local function set(f, patt) -- ./candran/can-parser/parser.lua:502 -return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:503 -end -- ./candran/can-parser/parser.lua:503 -local G = { -- ./candran/can-parser/parser.lua:507 -V("Lua"), -- ./candran/can-parser/parser.lua:507 -["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:508 +local function when(f) -- ./candran/can-parser/parser.lua:502 +return Cmt(P(""), function() -- ./candran/can-parser/parser.lua:503 +return # stacks[f] > 0 -- ./candran/can-parser/parser.lua:504 +end) -- ./candran/can-parser/parser.lua:504 +end -- ./candran/can-parser/parser.lua:504 +local function set(f, patt) -- ./candran/can-parser/parser.lua:507 +return push(f) * patt * pop(f) -- ./candran/can-parser/parser.lua:508 +end -- ./candran/can-parser/parser.lua:508 +local G = { -- ./candran/can-parser/parser.lua:512 +V("Lua"), -- ./candran/can-parser/parser.lua:512 +["Lua"] = (V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra")) / fixStructure, -- ./candran/can-parser/parser.lua:513 ["Shebang"] = P("#!") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:509 -["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:511 -["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("ConstStat") + V("CloseStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:517 -["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:518 -["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:520 -t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:520 -return t -- ./candran/can-parser/parser.lua:520 -end, -- ./candran/can-parser/parser.lua:520 -["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:521 -["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:523 -["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:524 -["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:525 -["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:526 -["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:528 -["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:529 -["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:530 -["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:531 -["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:533 -["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:534 -["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:536 -["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:537 -["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:538 -["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:540 -["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:541 -["LocalAssign"] = tagC("Local", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:543 -["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:545 -["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:547 -["ConstStat"] = kw("const") * expect(V("AttributeAssign") / setAttribute("const"), "DefConst"), -- ./candran/can-parser/parser.lua:549 -["CloseStat"] = kw("close") * expect(V("AttributeAssign") / setAttribute("close"), "DefClose"), -- ./candran/can-parser/parser.lua:550 -["AttributeAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:552 -["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:554 -["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:556 -["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:558 -["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:559 -["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:560 -["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:563 -["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:565 -["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:566 -["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:568 -["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:570 -["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:571 -["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:573 -["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:574 -["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:575 -["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:576 -["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:577 -["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:579 -["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")), -- ./candran/can-parser/parser.lua:580 -["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:582 -["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:583 -["AttributeNameList"] = tagC("AttributeNameList", commaSep(V("AttributeId"))), -- ./candran/can-parser/parser.lua:584 -["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:585 -["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:586 -["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:588 -["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:589 -["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:591 -["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:593 -["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:594 -["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:595 -["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:596 -["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:597 -["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:598 -["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:599 -["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:600 -["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:601 -["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:602 -["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:603 -["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:605 -["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:606 -["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:616 -["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:618 -["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:620 -return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:620 -end), -- ./candran/can-parser/parser.lua:620 -["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:621 -return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:621 -end), -- ./candran/can-parser/parser.lua:621 -["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:625 -["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:628 -["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:629 -["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:633 -["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:635 -["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:637 -["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:638 -["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:639 -["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:641 -["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:644 -["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:646 -["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:647 -["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:649 -["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:651 -["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:652 -["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:654 -["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:656 -["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:657 -["AttributeSelfId"] = tagC("AttributeId", sym("@") / "self" * V("Attribute") ^ - 1), -- ./candran/can-parser/parser.lua:658 -["AttributeId"] = tagC("AttributeId", V("Name") * V("Attribute") ^ - 1) + V("AttributeSelfId"), -- ./candran/can-parser/parser.lua:659 -["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:660 -["Attribute"] = sym("<") * expect(kw("const") / "const" + kw("close") / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"), -- ./candran/can-parser/parser.lua:662 -["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:665 -["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:666 -["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:667 -return -- ./candran/can-parser/parser.lua:667 +")) ^ 0, -- ./candran/can-parser/parser.lua:514 +["Block"] = tagC("Block", (V("Stat") + - V("BlockEnd") * throw("InvalidStat")) ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:516 +["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("FuncStat") + V("BreakStat") + V("LabelStat") + V("GoToStat") + V("LetStat") + V("ConstStat") + V("CloseStat") + V("FuncCall") + V("Assignment") + V("ContinueStat") + V("PushStat") + sym(";"), -- ./candran/can-parser/parser.lua:522 +["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + "]" + - 1 + V("ImplicitPushStat") + V("Assignment"), -- ./candran/can-parser/parser.lua:523 +["SingleStatBlock"] = tagC("Block", V("Stat") + V("RetStat") + V("ImplicitPushStat")) / function(t) -- ./candran/can-parser/parser.lua:525 +t["is_singlestatblock"] = true -- ./candran/can-parser/parser.lua:525 +return t -- ./candran/can-parser/parser.lua:525 +end, -- ./candran/can-parser/parser.lua:525 +["BlockNoErr"] = tagC("Block", V("Stat") ^ 0 * ((V("RetStat") + V("ImplicitPushStat")) * sym(";") ^ - 1) ^ - 1), -- ./candran/can-parser/parser.lua:526 +["IfStat"] = tagC("If", V("IfPart")), -- ./candran/can-parser/parser.lua:528 +["IfPart"] = kw("if") * set("lexpr", expect(V("Expr"), "ExprIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:529 +["ElseIfPart"] = kw("elseif") * set("lexpr", expect(V("Expr"), "ExprEIf")) * expectBlockOrSingleStatWithStartEnd(kw("then"), "ThenEIf", "EndIf", V("ElseIfPart") + V("ElsePart")), -- ./candran/can-parser/parser.lua:530 +["ElsePart"] = kw("else") * expectBlockWithEnd("EndIf"), -- ./candran/can-parser/parser.lua:531 +["DoStat"] = kw("do") * expectBlockWithEnd("EndDo") / tagDo, -- ./candran/can-parser/parser.lua:533 +["WhileStat"] = tagC("While", kw("while") * set("lexpr", expect(V("Expr"), "ExprWhile")) * V("WhileBody")), -- ./candran/can-parser/parser.lua:534 +["WhileBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoWhile", "EndWhile"), -- ./candran/can-parser/parser.lua:535 +["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), -- ./candran/can-parser/parser.lua:536 +["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange"), -- ./candran/can-parser/parser.lua:538 +["ForNum"] = tagC("Fornum", V("Id") * sym("=") * V("NumRange") * V("ForBody")), -- ./candran/can-parser/parser.lua:539 +["NumRange"] = expect(V("Expr"), "ExprFor1") * expect(sym(","), "CommaFor") * expect(V("Expr"), "ExprFor2") * (sym(",") * expect(V("Expr"), "ExprFor3")) ^ - 1, -- ./candran/can-parser/parser.lua:541 +["ForIn"] = tagC("Forin", V("DestructuringNameList") * expect(kw("in"), "InFor") * expect(V("ExprList"), "EListFor") * V("ForBody")), -- ./candran/can-parser/parser.lua:542 +["ForBody"] = expectBlockOrSingleStatWithStartEnd(kw("do"), "DoFor", "EndFor"), -- ./candran/can-parser/parser.lua:543 +["LocalStat"] = kw("local") * expect(V("LocalFunc") + V("LocalAssign"), "DefLocal"), -- ./candran/can-parser/parser.lua:545 +["LocalFunc"] = tagC("Localrec", kw("function") * expect(V("Id"), "NameLFunc") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:546 +["LocalAssign"] = tagC("Local", V("AttributeNameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:548 +["LetStat"] = kw("let") * expect(V("LetAssign"), "DefLet"), -- ./candran/can-parser/parser.lua:550 +["LetAssign"] = tagC("Let", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Let", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:552 +["ConstStat"] = kw("const") * expect(V("AttributeAssign") / setAttribute("const"), "DefConst"), -- ./candran/can-parser/parser.lua:554 +["CloseStat"] = kw("close") * expect(V("AttributeAssign") / setAttribute("close"), "DefClose"), -- ./candran/can-parser/parser.lua:555 +["AttributeAssign"] = tagC("Local", V("NameList") * (sym("=") * expect(V("ExprList"), "EListLAssign") + Ct(Cc()))) + tagC("Local", V("DestructuringNameList") * sym("=") * expect(V("ExprList"), "EListLAssign")), -- ./candran/can-parser/parser.lua:557 +["Assignment"] = tagC("Set", (V("VarList") + V("DestructuringNameList")) * V("BinOp") ^ - 1 * (P("=") / "=") * ((V("BinOp") - P("-")) + # (P("-") * V("Space")) * V("BinOp")) ^ - 1 * V("Skip") * expect(V("ExprList"), "EListAssign")), -- ./candran/can-parser/parser.lua:559 +["FuncStat"] = tagC("Set", kw("function") * expect(V("FuncName"), "FuncName") * V("FuncBody")) / fixFuncStat, -- ./candran/can-parser/parser.lua:561 +["FuncName"] = Cf(V("Id") * (sym(".") * expect(V("StrId"), "NameFunc1")) ^ 0, insertIndex) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, -- ./candran/can-parser/parser.lua:563 +["FuncBody"] = tagC("Function", V("FuncParams") * expectBlockWithEnd("EndFunc")), -- ./candran/can-parser/parser.lua:564 +["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), -- ./candran/can-parser/parser.lua:565 +["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), -- ./candran/can-parser/parser.lua:568 +["ShortFuncDef"] = tagC("Function", V("ShortFuncParams") * maybeBlockWithEnd()) / fixShortFunc, -- ./candran/can-parser/parser.lua:570 +["ShortFuncParams"] = (sym(":") / ":") ^ - 1 * sym("(") * V("ParList") * sym(")"), -- ./candran/can-parser/parser.lua:571 +["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), -- ./candran/can-parser/parser.lua:573 +["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:575 +["ParKey"] = V("Id") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:576 +["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), -- ./candran/can-parser/parser.lua:578 +["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), -- ./candran/can-parser/parser.lua:579 +["BreakStat"] = tagC("Break", kw("break")), -- ./candran/can-parser/parser.lua:580 +["ContinueStat"] = tagC("Continue", kw("continue")), -- ./candran/can-parser/parser.lua:581 +["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:582 +["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1), -- ./candran/can-parser/parser.lua:584 +["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList")) / markImplicit, -- ./candran/can-parser/parser.lua:585 +["NameList"] = tagC("NameList", commaSep(V("Id"))), -- ./candran/can-parser/parser.lua:587 +["DestructuringNameList"] = tagC("NameList", commaSep(V("DestructuringId"))), -- ./candran/can-parser/parser.lua:588 +["AttributeNameList"] = tagC("AttributeNameList", commaSep(V("AttributeId"))), -- ./candran/can-parser/parser.lua:589 +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), -- ./candran/can-parser/parser.lua:590 +["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), -- ./candran/can-parser/parser.lua:591 +["DestructuringId"] = tagC("DestructuringId", sym("{") * V("DestructuringIdFieldList") * expect(sym("}"), "CBraceDestructuring")) + V("Id"), -- ./candran/can-parser/parser.lua:593 +["DestructuringIdFieldList"] = sepBy(V("DestructuringIdField"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:594 +["DestructuringIdField"] = tagC("Pair", V("FieldKey") * expect(sym("="), "DestructuringEqField") * expect(V("Id"), "DestructuringExprField")) + V("Id"), -- ./candran/can-parser/parser.lua:596 +["Expr"] = V("OrExpr"), -- ./candran/can-parser/parser.lua:598 +["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), -- ./candran/can-parser/parser.lua:599 +["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), -- ./candran/can-parser/parser.lua:600 +["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), -- ./candran/can-parser/parser.lua:601 +["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), -- ./candran/can-parser/parser.lua:602 +["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), -- ./candran/can-parser/parser.lua:603 +["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), -- ./candran/can-parser/parser.lua:604 +["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), -- ./candran/can-parser/parser.lua:605 +["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:606 +["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), -- ./candran/can-parser/parser.lua:607 +["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), -- ./candran/can-parser/parser.lua:608 +["UnaryExpr"] = V("UnaryOp") * expect(V("UnaryExpr"), "UnaryExpr") / unaryOp + V("PowExpr"), -- ./candran/can-parser/parser.lua:610 +["PowExpr"] = V("SimpleExpr") * (V("PowOp") * expect(V("UnaryExpr"), "PowExpr")) ^ - 1 / binaryOp, -- ./candran/can-parser/parser.lua:611 +["SimpleExpr"] = tagC("Number", V("Number")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + (when("lexpr") * tagC("LetExpr", maybe(V("DestructuringNameList")) * sym("=") * - sym("=") * expect(V("ExprList"), "EListLAssign"))) + V("ShortFuncDef") + V("SuffixedExpr") + V("StatExpr"), -- ./candran/can-parser/parser.lua:621 +["StatExpr"] = (V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat")) / statToExpr, -- ./candran/can-parser/parser.lua:623 +["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:625 +return exp["tag"] == "Call" or exp["tag"] == "SafeCall", exp -- ./candran/can-parser/parser.lua:625 +end), -- ./candran/can-parser/parser.lua:625 +["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp) -- ./candran/can-parser/parser.lua:626 +return exp["tag"] == "Id" or exp["tag"] == "Index", exp -- ./candran/can-parser/parser.lua:626 +end), -- ./candran/can-parser/parser.lua:626 +["SuffixedExpr"] = Cf(V("PrimaryExpr") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr") * - V("Call") * (V("Index") + V("MethodStub") + V("Call")) ^ 0 + V("NoCallPrimaryExpr"), makeSuffixedExpr), -- ./candran/can-parser/parser.lua:630 +["PrimaryExpr"] = V("SelfId") * (V("SelfCall") + V("SelfIndex")) + V("Id") + tagC("Paren", sym("(") * expect(V("Expr"), "ExprParen") * expect(sym(")"), "CParenExpr")), -- ./candran/can-parser/parser.lua:633 +["NoCallPrimaryExpr"] = tagC("String", V("String")) + V("Table") + V("TableCompr"), -- ./candran/can-parser/parser.lua:634 +["Index"] = tagC("DotIndex", sym("." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("ArrayIndex", sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")) + tagC("SafeDotIndex", sym("?." * - P(".")) * expect(V("StrId"), "NameIndex")) + tagC("SafeArrayIndex", sym("?[" * - P(S("=["))) * expect(V("Expr"), "ExprIndex") * expect(sym("]"), "CBracketIndex")), -- ./candran/can-parser/parser.lua:638 +["MethodStub"] = tagC("MethodStub", sym(":" * - P(":")) * expect(V("StrId"), "NameMeth")) + tagC("SafeMethodStub", sym("?:" * - P(":")) * expect(V("StrId"), "NameMeth")), -- ./candran/can-parser/parser.lua:640 +["Call"] = tagC("Call", V("FuncArgs")) + tagC("SafeCall", P("?") * V("FuncArgs")), -- ./candran/can-parser/parser.lua:642 +["SelfCall"] = tagC("MethodStub", V("StrId")) * V("Call"), -- ./candran/can-parser/parser.lua:643 +["SelfIndex"] = tagC("DotIndex", V("StrId")), -- ./candran/can-parser/parser.lua:644 +["FuncDef"] = (kw("function") * V("FuncBody")), -- ./candran/can-parser/parser.lua:646 +["FuncArgs"] = sym("(") * commaSep(V("Expr"), "ArgList") ^ - 1 * expect(sym(")"), "CParenArgs") + V("Table") + tagC("String", V("String")), -- ./candran/can-parser/parser.lua:649 +["Table"] = tagC("Table", sym("{") * V("FieldList") ^ - 1 * expect(sym("}"), "CBraceTable")), -- ./candran/can-parser/parser.lua:651 +["FieldList"] = sepBy(V("Field"), V("FieldSep")) * V("FieldSep") ^ - 1, -- ./candran/can-parser/parser.lua:652 +["Field"] = tagC("Pair", V("FieldKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Expr"), -- ./candran/can-parser/parser.lua:654 +["FieldKey"] = sym("[" * - P(S("=["))) * expect(V("Expr"), "ExprFKey") * expect(sym("]"), "CBracketFKey") + V("StrId") * # ("=" * - P("=")), -- ./candran/can-parser/parser.lua:656 +["FieldSep"] = sym(",") + sym(";"), -- ./candran/can-parser/parser.lua:657 +["TableCompr"] = tagC("TableCompr", sym("[") * V("Block") * expect(sym("]"), "CBracketTableCompr")), -- ./candran/can-parser/parser.lua:659 +["SelfId"] = tagC("Id", sym("@") / "self"), -- ./candran/can-parser/parser.lua:661 +["Id"] = tagC("Id", V("Name")) + V("SelfId"), -- ./candran/can-parser/parser.lua:662 +["AttributeSelfId"] = tagC("AttributeId", sym("@") / "self" * V("Attribute") ^ - 1), -- ./candran/can-parser/parser.lua:663 +["AttributeId"] = tagC("AttributeId", V("Name") * V("Attribute") ^ - 1) + V("AttributeSelfId"), -- ./candran/can-parser/parser.lua:664 +["StrId"] = tagC("String", V("Name")), -- ./candran/can-parser/parser.lua:665 +["Attribute"] = sym("<") * expect(kw("const") / "const" + kw("close") / "close", "UnknownAttribute") * expect(sym(">"), "CBracketAttribute"), -- ./candran/can-parser/parser.lua:667 +["Skip"] = (V("Space") + V("Comment")) ^ 0, -- ./candran/can-parser/parser.lua:670 +["Space"] = space ^ 1, -- ./candran/can-parser/parser.lua:671 +["Comment"] = P("--") * V("LongStr") / function() -- ./candran/can-parser/parser.lua:672 +return -- ./candran/can-parser/parser.lua:672 end + P("--") * (P(1) - P("\ -")) ^ 0, -- ./candran/can-parser/parser.lua:668 -["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:670 -["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:671 -["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:675 -["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:676 -["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:677 -["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:678 -["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:680 -["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:681 -["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:683 -["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:685 -["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:686 -["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:687 -["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:688 -["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:689 -["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:691 +")) ^ 0, -- ./candran/can-parser/parser.lua:673 +["Name"] = token(- V("Reserved") * C(V("Ident"))), -- ./candran/can-parser/parser.lua:675 +["Reserved"] = V("Keywords") * - V("IdRest"), -- ./candran/can-parser/parser.lua:676 +["Keywords"] = P("and") + "break" + "do" + "elseif" + "else" + "end" + "false" + "for" + "function" + "goto" + "if" + "in" + "local" + "nil" + "not" + "or" + "repeat" + "return" + "then" + "true" + "until" + "while", -- ./candran/can-parser/parser.lua:680 +["Ident"] = V("IdStart") * V("IdRest") ^ 0, -- ./candran/can-parser/parser.lua:681 +["IdStart"] = alpha + P("_"), -- ./candran/can-parser/parser.lua:682 +["IdRest"] = alnum + P("_"), -- ./candran/can-parser/parser.lua:683 +["Number"] = token(C(V("Hex") + V("Float") + V("Int"))), -- ./candran/can-parser/parser.lua:685 +["Hex"] = (P("0x") + "0X") * ((xdigit ^ 0 * V("DeciHex")) + (expect(xdigit ^ 1, "DigitHex") * V("DeciHex") ^ - 1)) * V("ExpoHex") ^ - 1, -- ./candran/can-parser/parser.lua:686 +["Float"] = V("Decimal") * V("Expo") ^ - 1 + V("Int") * V("Expo"), -- ./candran/can-parser/parser.lua:688 +["Decimal"] = digit ^ 1 * "." * digit ^ 0 + P(".") * - P(".") * expect(digit ^ 1, "DigitDeci"), -- ./candran/can-parser/parser.lua:690 +["DeciHex"] = P(".") * xdigit ^ 0, -- ./candran/can-parser/parser.lua:691 +["Expo"] = S("eE") * S("+-") ^ - 1 * expect(digit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:692 +["ExpoHex"] = S("pP") * S("+-") ^ - 1 * expect(xdigit ^ 1, "DigitExpo"), -- ./candran/can-parser/parser.lua:693 +["Int"] = digit ^ 1, -- ./candran/can-parser/parser.lua:694 +["String"] = token(V("ShortStr") + V("LongStr")), -- ./candran/can-parser/parser.lua:696 ["ShortStr"] = P("\"") * Cs((V("EscSeq") + (P(1) - S("\"\ "))) ^ 0) * expect(P("\""), "Quote") + P("'") * Cs((V("EscSeq") + (P(1) - S("'\ -"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:693 -["EscSeq"] = P("\\") / "" * (P("a") / "" + P("b") / "" + P("f") / " " + P("n") / "\ -" + P("r") / "\r" + P("t") / " " + P("v") / " " + P("\ +"))) ^ 0) * expect(P("'"), "Quote"), -- ./candran/can-parser/parser.lua:698 +["EscSeq"] = P("\\") / "" * (P("a") / "\7" + P("b") / "\8" + P("f") / "\12" + P("n") / "\ +" + P("r") / "\13" + P("t") / "\9" + P("v") / "\11" + P("\ ") / "\ -" + P("\r") / "\ -" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:723 -["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:726 -return s -- ./candran/can-parser/parser.lua:726 -end, -- ./candran/can-parser/parser.lua:726 +" + P("\13") / "\ +" + P("\\") / "\\" + P("\"") / "\"" + P("'") / "'" + P("z") * space ^ 0 / "" + digit * digit ^ - 2 / tonumber / string["char"] + P("x") * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string["char"] + P("u") * expect("{", "OBraceUEsc") * expect(C(xdigit ^ 1), "DigitUEsc") * Cc(16) * expect("}", "CBraceUEsc") / tonumber / (utf8 and utf8["char"] or string["char"]) + throw("EscSeq")), -- ./candran/can-parser/parser.lua:728 +["LongStr"] = V("Open") * C((P(1) - V("CloseEq")) ^ 0) * expect(V("Close"), "CloseLStr") / function(s, eqs) -- ./candran/can-parser/parser.lua:731 +return s -- ./candran/can-parser/parser.lua:731 +end, -- ./candran/can-parser/parser.lua:731 ["Open"] = "[" * Cg(V("Equals"), "openEq") * "[" * P("\ -") ^ - 1, -- ./candran/can-parser/parser.lua:727 -["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:728 -["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:729 -["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:730 -return # openEq == # closeEq -- ./candran/can-parser/parser.lua:730 -end), -- ./candran/can-parser/parser.lua:730 -["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:732 -["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:733 -["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:739 -["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:740 -["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:741 -["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:742 -["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:744 -["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:745 -["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:747 -["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:751 -["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:755 -["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:756 -["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:757 -} -- ./candran/can-parser/parser.lua:757 -local parser = {} -- ./candran/can-parser/parser.lua:760 -local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:762 -local validate = validator["validate"] -- ./candran/can-parser/parser.lua:763 -local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:764 -parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:766 -local errorinfo = { -- ./candran/can-parser/parser.lua:767 -["subject"] = subject, -- ./candran/can-parser/parser.lua:767 -["filename"] = filename -- ./candran/can-parser/parser.lua:767 -} -- ./candran/can-parser/parser.lua:767 -lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:768 -local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:769 -if not ast then -- ./candran/can-parser/parser.lua:770 -local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:771 -return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:772 -end -- ./candran/can-parser/parser.lua:772 -return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:774 -end -- ./candran/can-parser/parser.lua:774 -return parser -- ./candran/can-parser/parser.lua:777 +") ^ - 1, -- ./candran/can-parser/parser.lua:732 +["Close"] = "]" * C(V("Equals")) * "]", -- ./candran/can-parser/parser.lua:733 +["Equals"] = P("=") ^ 0, -- ./candran/can-parser/parser.lua:734 +["CloseEq"] = Cmt(V("Close") * Cb("openEq"), function(s, i, closeEq, openEq) -- ./candran/can-parser/parser.lua:735 +return # openEq == # closeEq -- ./candran/can-parser/parser.lua:735 +end), -- ./candran/can-parser/parser.lua:735 +["OrOp"] = kw("or") / "or", -- ./candran/can-parser/parser.lua:737 +["AndOp"] = kw("and") / "and", -- ./candran/can-parser/parser.lua:738 +["RelOp"] = sym("~=") / "ne" + sym("==") / "eq" + sym("<=") / "le" + sym(">=") / "ge" + sym("<") / "lt" + sym(">") / "gt", -- ./candran/can-parser/parser.lua:744 +["BOrOp"] = sym("|") / "bor", -- ./candran/can-parser/parser.lua:745 +["BXorOp"] = sym("~" * - P("=")) / "bxor", -- ./candran/can-parser/parser.lua:746 +["BAndOp"] = sym("&") / "band", -- ./candran/can-parser/parser.lua:747 +["ShiftOp"] = sym("<<") / "shl" + sym(">>") / "shr", -- ./candran/can-parser/parser.lua:749 +["ConcatOp"] = sym("..") / "concat", -- ./candran/can-parser/parser.lua:750 +["AddOp"] = sym("+") / "add" + sym("-") / "sub", -- ./candran/can-parser/parser.lua:752 +["MulOp"] = sym("*") / "mul" + sym("//") / "idiv" + sym("/") / "div" + sym("%") / "mod", -- ./candran/can-parser/parser.lua:756 +["UnaryOp"] = kw("not") / "not" + sym("-") / "unm" + sym("#") / "len" + sym("~") / "bnot", -- ./candran/can-parser/parser.lua:760 +["PowOp"] = sym("^") / "pow", -- ./candran/can-parser/parser.lua:761 +["BinOp"] = V("OrOp") + V("AndOp") + V("BOrOp") + V("BXorOp") + V("BAndOp") + V("ShiftOp") + V("ConcatOp") + V("AddOp") + V("MulOp") + V("PowOp") -- ./candran/can-parser/parser.lua:762 +} -- ./candran/can-parser/parser.lua:762 +local macroidentifier = { -- ./candran/can-parser/parser.lua:766 +expect(V("MacroIdentifier"), "InvalidStat") * expect(P(- 1), "Extra"), -- ./candran/can-parser/parser.lua:767 +["MacroIdentifier"] = tagC("MacroFunction", V("Id") * sym("(") * V("MacroFunctionArgs") * expect(sym(")"), "CParenPList")) + V("Id"), -- ./candran/can-parser/parser.lua:770 +["MacroFunctionArgs"] = V("NameList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()) -- ./candran/can-parser/parser.lua:774 +} -- ./candran/can-parser/parser.lua:774 +for k, v in pairs(G) do -- ./candran/can-parser/parser.lua:777 +if macroidentifier[k] == nil then -- ./candran/can-parser/parser.lua:777 +macroidentifier[k] = v -- ./candran/can-parser/parser.lua:777 end -- ./candran/can-parser/parser.lua:777 -local parser = _() or parser -- ./candran/can-parser/parser.lua:781 -package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:782 +end -- ./candran/can-parser/parser.lua:777 +local parser = {} -- ./candran/can-parser/parser.lua:779 +local validator = require("candran.can-parser.validator") -- ./candran/can-parser/parser.lua:781 +local validate = validator["validate"] -- ./candran/can-parser/parser.lua:782 +local syntaxerror = validator["syntaxerror"] -- ./candran/can-parser/parser.lua:783 +parser["parse"] = function(subject, filename) -- ./candran/can-parser/parser.lua:785 +local errorinfo = { -- ./candran/can-parser/parser.lua:786 +["subject"] = subject, -- ./candran/can-parser/parser.lua:786 +["filename"] = filename -- ./candran/can-parser/parser.lua:786 +} -- ./candran/can-parser/parser.lua:786 +lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:787 +local ast, label, errpos = lpeg["match"](G, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:788 +if not ast then -- ./candran/can-parser/parser.lua:789 +local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:790 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:791 +end -- ./candran/can-parser/parser.lua:791 +return validate(ast, errorinfo) -- ./candran/can-parser/parser.lua:793 +end -- ./candran/can-parser/parser.lua:793 +parser["parsemacroidentifier"] = function(subject, filename) -- ./candran/can-parser/parser.lua:796 +local errorinfo = { -- ./candran/can-parser/parser.lua:797 +["subject"] = subject, -- ./candran/can-parser/parser.lua:797 +["filename"] = filename -- ./candran/can-parser/parser.lua:797 +} -- ./candran/can-parser/parser.lua:797 +lpeg["setmaxstack"](1000) -- ./candran/can-parser/parser.lua:798 +local ast, label, errpos = lpeg["match"](macroidentifier, subject, nil, errorinfo) -- ./candran/can-parser/parser.lua:799 +if not ast then -- ./candran/can-parser/parser.lua:800 +local errmsg = labels[label][2] -- ./candran/can-parser/parser.lua:801 +return ast, syntaxerror(errorinfo, errpos, errmsg) -- ./candran/can-parser/parser.lua:802 +end -- ./candran/can-parser/parser.lua:802 +return ast -- ./candran/can-parser/parser.lua:804 +end -- ./candran/can-parser/parser.lua:804 +return parser -- ./candran/can-parser/parser.lua:807 +end -- ./candran/can-parser/parser.lua:807 +local parser = _() or parser -- ./candran/can-parser/parser.lua:811 +package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:812 local unpack = unpack or table["unpack"] -- candran.can:15 local candran = { ["VERSION"] = "0.14.0" } -- candran.can:18 package["loaded"]["candran"] = candran -- candran.can:20 @@ -6421,254 +6761,282 @@ candran["default"]["target"] = "lua52" -- candran.can:41 elseif _VERSION == "Lua 5.3" then -- candran.can:42 candran["default"]["target"] = "lua53" -- candran.can:43 end -- candran.can:43 -candran["preprocess"] = function(input, options) -- candran.can:52 -if options == nil then options = {} end -- candran.can:52 -options = util["merge"](candran["default"], options) -- candran.can:53 -local preprocessor = "" -- candran.can:56 -local i = 0 -- candran.can:57 -local inLongString = false -- candran.can:58 -local inComment = false -- candran.can:59 +candran["preprocess"] = function(input, options) -- candran.can:53 +if options == nil then options = {} end -- candran.can:53 +options = util["merge"](candran["default"], options) -- candran.can:54 +local macros = { -- candran.can:55 +["functions"] = {}, -- candran.can:56 +["variables"] = {} -- candran.can:57 +} -- candran.can:57 +local preprocessor = "" -- candran.can:61 +local i = 0 -- candran.can:62 +local inLongString = false -- candran.can:63 +local inComment = false -- candran.can:64 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:60 -i = i + (1) -- candran.can:61 -if inComment then -- candran.can:63 -inComment = not line:match("%]%]") -- candran.can:64 -elseif inLongString then -- candran.can:65 -inLongString = not line:match("%]%]") -- candran.can:66 -else -- candran.can:66 -if line:match("[^%-]%[%[") then -- candran.can:68 -inLongString = true -- candran.can:69 -elseif line:match("%-%-%[%[") then -- candran.can:70 -inComment = true -- candran.can:71 -end -- candran.can:71 -end -- candran.can:71 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:74 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:75 -else -- candran.can:75 -local l = line:sub(1, - 2) -- candran.can:77 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:78 +)") do -- candran.can:65 +i = i + (1) -- candran.can:66 +if inComment then -- candran.can:68 +inComment = not line:match("%]%]") -- candran.can:69 +elseif inLongString then -- candran.can:70 +inLongString = not line:match("%]%]") -- candran.can:71 +else -- candran.can:71 +if line:match("[^%-]%[%[") then -- candran.can:73 +inLongString = true -- candran.can:74 +elseif line:match("%-%-%[%[") then -- candran.can:75 +inComment = true -- candran.can:76 +end -- candran.can:76 +end -- candran.can:76 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:79 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:80 +else -- candran.can:80 +local l = line:sub(1, - 2) -- candran.can:82 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:83 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:79 -else -- candran.can:79 +") -- candran.can:84 +else -- candran.can:84 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:81 -end -- candran.can:81 -end -- candran.can:81 -end -- candran.can:81 -preprocessor = preprocessor .. ("return output") -- candran.can:85 -local env = util["merge"](_G, options) -- candran.can:88 -env["candran"] = candran -- candran.can:90 -env["output"] = "" -- candran.can:92 -env["import"] = function(modpath, margs) -- candran.can:99 -if margs == nil then margs = {} end -- candran.can:99 -local filepath = assert(util["search"](modpath, { -- candran.can:100 -"can", -- candran.can:100 -"lua" -- candran.can:100 -}), "No module named \"" .. modpath .. "\"") -- candran.can:100 -local f = io["open"](filepath) -- candran.can:103 -if not f then -- candran.can:104 -error("can't open the module file to import") -- candran.can:104 -end -- candran.can:104 -margs = util["merge"](options, { -- candran.can:106 -["chunkname"] = filepath, -- candran.can:106 -["loadLocal"] = true, -- candran.can:106 -["loadPackage"] = true -- candran.can:106 -}, margs) -- candran.can:106 -local modcontent = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:107 -f:close() -- candran.can:108 -local modname = modpath:match("[^%.]+$") -- candran.can:111 +") -- candran.can:86 +end -- candran.can:86 +end -- candran.can:86 +end -- candran.can:86 +preprocessor = preprocessor .. ("return output") -- candran.can:90 +local env = util["merge"](_G, options) -- candran.can:93 +env["candran"] = candran -- candran.can:95 +env["output"] = "" -- candran.can:97 +env["import"] = function(modpath, margs) -- candran.can:104 +if margs == nil then margs = {} end -- candran.can:104 +local filepath = assert(util["search"](modpath, { -- candran.can:105 +"can", -- candran.can:105 +"lua" -- candran.can:105 +}), "No module named \"" .. modpath .. "\"") -- candran.can:105 +local f = io["open"](filepath) -- candran.can:108 +if not f then -- candran.can:109 +error("can't open the module file to import") -- candran.can:109 +end -- candran.can:109 +margs = util["merge"](options, { -- candran.can:111 +["chunkname"] = filepath, -- candran.can:111 +["loadLocal"] = true, -- candran.can:111 +["loadPackage"] = true -- candran.can:111 +}, margs) -- candran.can:111 +local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:112 +macros = util["recmerge"](macros, modmacros) -- candran.can:113 +f:close() -- candran.can:114 +local modname = modpath:match("[^%.]+$") -- candran.can:117 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:120 -end -- candran.can:120 -env["include"] = function(file) -- candran.can:125 -local f = io["open"](file) -- candran.can:126 -if not f then -- candran.can:127 -error("can't open the file " .. file .. " to include") -- candran.can:127 -end -- candran.can:127 -env["write"](f:read("*a")) -- candran.can:128 -f:close() -- candran.can:129 -end -- candran.can:129 -env["write"] = function(...) -- candran.can:133 -env["output"] = env["output"] .. (table["concat"]({ ... }, " ") .. "\ -") -- candran.can:134 -end -- candran.can:134 -env["placeholder"] = function(name) -- candran.can:138 -if env[name] then -- candran.can:139 -env["write"](env[name]) -- candran.can:140 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:126 +end -- candran.can:126 +env["include"] = function(file) -- candran.can:131 +local f = io["open"](file) -- candran.can:132 +if not f then -- candran.can:133 +error("can't open the file " .. file .. " to include") -- candran.can:133 +end -- candran.can:133 +env["write"](f:read("*a")) -- candran.can:134 +f:close() -- candran.can:135 +end -- candran.can:135 +env["write"] = function(...) -- candran.can:139 +env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ +") -- candran.can:140 end -- candran.can:140 -end -- candran.can:140 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:145 -if not preprocess then -- candran.can:146 -return nil, "in preprocessor: " .. err -- candran.can:147 -end -- candran.can:147 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:150 -if not preprocess then -- candran.can:151 -return nil, "in preprocessor: " .. err -- candran.can:152 -end -- candran.can:152 -local success, output = pcall(preprocess) -- candran.can:156 -if not success then -- candran.can:157 -return nil, "in preprocessor: " .. output -- candran.can:158 +env["placeholder"] = function(name) -- candran.can:144 +if env[name] then -- candran.can:145 +env["write"](env[name]) -- candran.can:146 +end -- candran.can:146 +end -- candran.can:146 +env["define"] = function(identifier, replacement) -- candran.can:149 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:151 +if not iast then -- candran.can:152 +return error(("in macro identifier: %s"):format(ierr)) -- candran.can:153 +end -- candran.can:153 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:156 +if not rast then -- candran.can:157 +return error(("in macro replacement: %s"):format(rerr)) -- candran.can:158 end -- candran.can:158 -return output -- candran.can:161 -end -- candran.can:161 -candran["compile"] = function(input, options) -- candran.can:170 -if options == nil then options = {} end -- candran.can:170 -options = util["merge"](candran["default"], options) -- candran.can:171 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:173 -if not ast then -- candran.can:175 -return nil, errmsg -- candran.can:176 -end -- candran.can:176 -return require("compiler." .. options["target"])(input, ast, options) -- candran.can:179 -end -- candran.can:179 -candran["make"] = function(code, options) -- candran.can:188 -local r, err = candran["preprocess"](code, options) -- candran.can:189 -if r then -- candran.can:190 -r, err = candran["compile"](r, options) -- candran.can:191 -if r then -- candran.can:192 -return r -- candran.can:193 -end -- candran.can:193 -end -- candran.can:193 -return r, err -- candran.can:196 -end -- candran.can:196 -local errorRewritingActive = false -- candran.can:199 -local codeCache = {} -- candran.can:200 -candran["loadfile"] = function(filepath, env, options) -- candran.can:203 -local f, err = io["open"](filepath) -- candran.can:204 -if not f then -- candran.can:205 -return nil, ("cannot open %s"):format(err) -- candran.can:206 -end -- candran.can:206 -local content = f:read("*a") -- candran.can:208 -f:close() -- candran.can:209 -return candran["load"](content, filepath, env, options) -- candran.can:211 -end -- candran.can:211 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:216 -if options == nil then options = {} end -- candran.can:216 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:217 -local code, err = candran["make"](chunk, options) -- candran.can:219 -if not code then -- candran.can:220 -return code, err -- candran.can:221 -end -- candran.can:221 -codeCache[options["chunkname"]] = code -- candran.can:224 -local f -- candran.can:225 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:226 -if f == nil then -- candran.can:231 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:232 -end -- candran.can:232 -if options["rewriteErrors"] == false then -- candran.can:235 -return f -- candran.can:236 -else -- candran.can:236 -return function(...) -- candran.can:238 -if not errorRewritingActive then -- candran.can:239 -errorRewritingActive = true -- candran.can:240 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:241 -errorRewritingActive = false -- candran.can:242 -if t[1] == false then -- candran.can:243 -error(t[2], 0) -- candran.can:244 -end -- candran.can:244 -return unpack(t, 2) -- candran.can:246 -else -- candran.can:246 -return f(...) -- candran.can:248 -end -- candran.can:248 -end -- candran.can:248 -end -- candran.can:248 -end -- candran.can:248 -candran["dofile"] = function(filename, options) -- candran.can:256 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:257 -if f == nil then -- candran.can:259 -error(err) -- candran.can:260 -else -- candran.can:260 -return f() -- candran.can:262 -end -- candran.can:262 -end -- candran.can:262 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:268 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:161 +rast = rast[1][1] -- candran.can:162 +end -- candran.can:162 +if iast["tag"] == "MacroFunction" then -- candran.can:165 +macros["functions"][iast[1][1]] = { -- candran.can:166 +["args"] = iast[2], -- candran.can:166 +["replacement"] = rast -- candran.can:166 +} -- candran.can:166 +elseif iast["tag"] == "Id" then -- candran.can:167 +macros["variables"][iast[1]] = rast -- candran.can:168 +else -- candran.can:168 +error(("invalid macro type %s"):format(iast["tag"])) -- candran.can:170 +end -- candran.can:170 +end -- candran.can:170 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:175 +if not preprocess then -- candran.can:176 +return nil, "in preprocessor: " .. err -- candran.can:177 +end -- candran.can:177 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:180 +if not preprocess then -- candran.can:181 +return nil, "in preprocessor: " .. err -- candran.can:182 +end -- candran.can:182 +local success, output = pcall(preprocess) -- candran.can:186 +if not success then -- candran.can:187 +return nil, "in preprocessor: " .. output -- candran.can:188 +end -- candran.can:188 +return output, macros -- candran.can:191 +end -- candran.can:191 +candran["compile"] = function(input, options, macros) -- candran.can:201 +if options == nil then options = {} end -- candran.can:201 +options = util["merge"](candran["default"], options) -- candran.can:202 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:204 +if not ast then -- candran.can:206 +return nil, errmsg -- candran.can:207 +end -- candran.can:207 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:210 +end -- candran.can:210 +candran["make"] = function(code, options) -- candran.can:219 +local r, err = candran["preprocess"](code, options) -- candran.can:220 +if r then -- candran.can:221 +r, err = candran["compile"](r, options, err) -- candran.can:222 +if r then -- candran.can:223 +return r -- candran.can:224 +end -- candran.can:224 +end -- candran.can:224 +return r, err -- candran.can:227 +end -- candran.can:227 +local errorRewritingActive = false -- candran.can:230 +local codeCache = {} -- candran.can:231 +candran["loadfile"] = function(filepath, env, options) -- candran.can:234 +local f, err = io["open"](filepath) -- candran.can:235 +if not f then -- candran.can:236 +return nil, ("cannot open %s"):format(err) -- candran.can:237 +end -- candran.can:237 +local content = f:read("*a") -- candran.can:239 +f:close() -- candran.can:240 +return candran["load"](content, filepath, env, options) -- candran.can:242 +end -- candran.can:242 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:247 +if options == nil then options = {} end -- candran.can:247 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:248 +local code, err = candran["make"](chunk, options) -- candran.can:250 +if not code then -- candran.can:251 +return code, err -- candran.can:252 +end -- candran.can:252 +codeCache[options["chunkname"]] = code -- candran.can:255 +local f -- candran.can:256 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:257 +if f == nil then -- candran.can:262 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:263 +end -- candran.can:263 +if options["rewriteErrors"] == false then -- candran.can:266 +return f -- candran.can:267 +else -- candran.can:267 +return function(...) -- candran.can:269 +if not errorRewritingActive then -- candran.can:270 +errorRewritingActive = true -- candran.can:271 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:272 +errorRewritingActive = false -- candran.can:273 +if t[1] == false then -- candran.can:274 +error(t[2], 0) -- candran.can:275 +end -- candran.can:275 +return unpack(t, 2) -- candran.can:277 +else -- candran.can:277 +return f(...) -- candran.can:279 +end -- candran.can:279 +end -- candran.can:279 +end -- candran.can:279 +end -- candran.can:279 +candran["dofile"] = function(filename, options) -- candran.can:287 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:288 +if f == nil then -- candran.can:290 +error(err) -- candran.can:291 +else -- candran.can:291 +return f() -- candran.can:293 +end -- candran.can:293 +end -- candran.can:293 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:299 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:269 -message = debug["traceback"](message, 2) -- candran.can:270 -end -- candran.can:270 +") then -- candran.can:300 +message = debug["traceback"](message, 2) -- candran.can:301 +end -- candran.can:301 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:272 -line = tonumber(line) -- candran.can:273 -local originalFile -- candran.can:275 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:276 -if strName then -- candran.can:277 -if codeCache[strName] then -- candran.can:278 -originalFile = codeCache[strName] -- candran.can:279 -source = strName -- candran.can:280 -end -- candran.can:280 -else -- candran.can:280 -do -- candran.can:283 -local fi -- candran.can:283 -fi = io["open"](source, "r") -- candran.can:283 -if fi then -- candran.can:283 -originalFile = fi:read("*a") -- candran.can:284 -fi:close() -- candran.can:285 -end -- candran.can:285 -end -- candran.can:285 -end -- candran.can:285 -if originalFile then -- candran.can:289 -local i = 0 -- candran.can:290 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:303 +line = tonumber(line) -- candran.can:304 +local originalFile -- candran.can:306 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:307 +if strName then -- candran.can:308 +if codeCache[strName] then -- candran.can:309 +originalFile = codeCache[strName] -- candran.can:310 +source = strName -- candran.can:311 +end -- candran.can:311 +else -- candran.can:311 +do -- candran.can:314 +local fi -- candran.can:314 +fi = io["open"](source, "r") -- candran.can:314 +if fi then -- candran.can:314 +originalFile = fi:read("*a") -- candran.can:315 +fi:close() -- candran.can:316 +end -- candran.can:316 +end -- candran.can:316 +end -- candran.can:316 +if originalFile then -- candran.can:320 +local i = 0 -- candran.can:321 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:291 -i = i + 1 -- candran.can:292 -if i == line then -- candran.can:293 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:294 -if lineMap then -- candran.can:295 -if extSource ~= source then -- candran.can:296 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:297 -else -- candran.can:297 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:299 -end -- candran.can:299 -end -- candran.can:299 -break -- candran.can:302 -end -- candran.can:302 -end -- candran.can:302 -end -- candran.can:302 -end) -- candran.can:302 -end -- candran.can:302 -candran["searcher"] = function(modpath) -- candran.can:310 -local filepath = util["search"](modpath, { "can" }) -- candran.can:311 -if not filepath then -- candran.can:312 -if _VERSION == "Lua 5.4" then -- candran.can:313 -return "no candran file in package.path" -- candran.can:314 -else -- candran.can:314 +") do -- candran.can:322 +i = i + 1 -- candran.can:323 +if i == line then -- candran.can:324 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:325 +if lineMap then -- candran.can:326 +if extSource ~= source then -- candran.can:327 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:328 +else -- candran.can:328 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:330 +end -- candran.can:330 +end -- candran.can:330 +break -- candran.can:333 +end -- candran.can:333 +end -- candran.can:333 +end -- candran.can:333 +end) -- candran.can:333 +end -- candran.can:333 +candran["searcher"] = function(modpath) -- candran.can:341 +local filepath = util["search"](modpath, { "can" }) -- candran.can:342 +if not filepath then -- candran.can:343 +if _VERSION == "Lua 5.4" then -- candran.can:344 +return "no candran file in package.path" -- candran.can:345 +else -- candran.can:345 return "\ - no candran file in package.path" -- candran.can:316 -end -- candran.can:316 -end -- candran.can:316 -return function(modpath) -- candran.can:319 -local r, s = candran["loadfile"](filepath) -- candran.can:320 -if r then -- candran.can:321 -return r(modpath, filepath) -- candran.can:322 -else -- candran.can:322 +\9no candran file in package.path" -- candran.can:347 +end -- candran.can:347 +end -- candran.can:347 +return function(modpath) -- candran.can:350 +local r, s = candran["loadfile"](filepath) -- candran.can:351 +if r then -- candran.can:352 +return r(modpath, filepath) -- candran.can:353 +else -- candran.can:353 error(("error loading candran module '%s' from file '%s':\ - %s"):format(modpath, filepath, s), 0) -- candran.can:324 -end -- candran.can:324 -end, filepath -- candran.can:326 -end -- candran.can:326 -candran["setup"] = function() -- candran.can:330 -local searchers = (function() -- candran.can:331 -if _VERSION == "Lua 5.1" then -- candran.can:331 -return package["loaders"] -- candran.can:332 -else -- candran.can:332 -return package["searchers"] -- candran.can:334 -end -- candran.can:334 -end)() -- candran.can:334 -for _, s in ipairs(searchers) do -- candran.can:337 -if s == candran["searcher"] then -- candran.can:338 -return candran -- candran.can:339 -end -- candran.can:339 -end -- candran.can:339 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:343 -return candran -- candran.can:344 -end -- candran.can:344 -return candran -- candran.can:347 +\9%s"):format(modpath, filepath, s), 0) -- candran.can:355 +end -- candran.can:355 +end, filepath -- candran.can:357 +end -- candran.can:357 +candran["setup"] = function() -- candran.can:361 +local searchers = (function() -- candran.can:362 +if _VERSION == "Lua 5.1" then -- candran.can:362 +return package["loaders"] -- candran.can:363 +else -- candran.can:363 +return package["searchers"] -- candran.can:365 +end -- candran.can:365 +end)() -- candran.can:365 +for _, s in ipairs(searchers) do -- candran.can:368 +if s == candran["searcher"] then -- candran.can:369 +return candran -- candran.can:370 +end -- candran.can:370 +end -- candran.can:370 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:374 +return candran -- candran.can:375 +end -- candran.can:375 +return candran -- candran.can:378 diff --git a/candran/can-parser/parser.lua b/candran/can-parser/parser.lua index 6efe5c7..5b44859 100644 --- a/candran/can-parser/parser.lua +++ b/candran/can-parser/parser.lua @@ -306,6 +306,11 @@ local function fixShortFunc (t) return t end +local function markImplicit (t) + t.implicit = true + return t +end + local function statToExpr (t) -- tag a StatExpr t.tag = t.tag .. "Expr" return t @@ -577,7 +582,7 @@ local G = { V"Lua", RetStat = tagC("Return", kw("return") * commaSep(V"Expr", "RetList")^-1); PushStat = tagC("Push", kw("push") * commaSep(V"Expr", "RetList")^-1); - ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList")); + ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList")) / markImplicit; NameList = tagC("NameList", commaSep(V"Id")); DestructuringNameList = tagC("NameList", commaSep(V"DestructuringId")), @@ -757,6 +762,20 @@ local G = { V"Lua", BinOp = V"OrOp" + V"AndOp" + V"BOrOp" + V"BXorOp" + V"BAndOp" + V"ShiftOp" + V"ConcatOp" + V"AddOp" + V"MulOp" + V"PowOp"; } +-- used to parse macro indentifier in define() preprocessor function +local macroidentifier = { + expect(V"MacroIdentifier", "InvalidStat") * expect(P(-1), "Extra"), + + MacroIdentifier = tagC("MacroFunction", V"Id" * sym("(") * V"MacroFunctionArgs" * expect(sym(")"), "CParenPList")) + + V"Id"; + + MacroFunctionArgs = V"NameList" * (sym(",") * expect(tagC("Dots", sym("...")), "ParList"))^-1 / addDots + + Ct(tagC("Dots", sym("..."))) + + Ct(Cc()); + +} +for k,v in pairs(G) do if macroidentifier[k] == nil then macroidentifier[k] = v end end -- copy other rules from main syntax + local parser = {} local validator = require("candran.can-parser.validator") @@ -774,4 +793,15 @@ function parser.parse (subject, filename) return validate(ast, errorinfo) end +function parser.parsemacroidentifier (subject, filename) + local errorinfo = { subject = subject, filename = filename } + lpeg.setmaxstack(1000) + local ast, label, errpos = lpeg.match(macroidentifier, subject, nil, errorinfo) + if not ast then + local errmsg = labels[label][2] + return ast, syntaxerror(errorinfo, errpos, errmsg) + end + return ast +end + return parser diff --git a/candran/util.can b/candran/util.can index 2beb260..c03689b 100644 --- a/candran/util.can +++ b/candran/util.can @@ -27,6 +27,20 @@ function util.load(str, name, env) end end +function util.recmerge(...) + local r = {} + for _, t in ipairs({...}) do + for k, v in pairs(t) do + if type(v) == "table" then + r[k] = util.merge(v, r[k]) + else + r[k] = v + end + end + end + return r +end + function util.merge(...) local r = {} for _, t in ipairs({...}) do diff --git a/compiler/lua54.can b/compiler/lua54.can index 6ce91a8..f8a3df8 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -1,6 +1,8 @@ +local util = require("candran.util") + local targetName = "Lua 5.4" -return function(code, ast, options) +return function(code, ast, options, macros={functions={}, variables={}}) --- Line mapping local lastInputPos = 1 -- last token position in the input code local prevLinePos = 1 -- last token position in the previous line of code in the input code @@ -47,7 +49,8 @@ return function(code, ast, options) local states = { push = {}, -- push stack variable names destructuring = {}, -- list of variable that need to be assigned from a destructure {id = "parent variable", "field1", "field2"...} - scope = {} -- list of variables defined in the current scope + scope = {}, -- list of variables defined in the current scope + macroargs = {} -- currently defined arguemnts from a macro function } -- Push a new value on top of the stack "name". Returns an empty string for chaining. local function push(name, state) @@ -83,6 +86,9 @@ return function(code, ast, options) return var end + -- indicate if currently processing a macro, so it cannot be applied recursively + local nomacro = { variables = {}, functions = {} } + --- Module management local required = {} -- { ["full require expression"] = true, ... } local requireStr = "" @@ -536,7 +542,15 @@ return function(code, ast, options) end, -- Dots Dots = () - return "..." + local macroargs = peek("macroargs") + if macroargs and not nomacro.variables["..."] and macroargs["..."] then + nomacro.variables["..."] = true + local r = lua(macroargs["..."], "_lhs") + nomacro.variables["..."] = nil + return r + else + return "..." + end end, -- Boolean{ } Boolean = (t) @@ -723,6 +737,28 @@ return function(code, ast, options) Call = (t) if t[1].tag == "String" or t[1].tag == "Table" then return "("..lua(t[1])..")("..lua(t, "_lhs", 2)..")" + elseif t[1].tag == "Id" and not nomacro.functions[t[1][1]] and macros.functions[t[1][1]] then + local macro = macros.functions[t[1][1]] + local replacement = macro.replacement + local macroargs = util.merge(peek("macroargs")) + for i, arg in ipairs(macro.args) do + if arg.tag == "Dots" then + macroargs["..."] = [for j=i+1, #t do t[j] end] + elseif arg.tag == "Id" then + if t[i+1] == nil then + error("bad argument #%s to macro %s (value expected)":format(i, t[1][1])) + end + macroargs[arg[1]] = t[i+1] + else + error("unexpected argument type %s in macro %s":format(arg.tag, t[1][1])) + end + end + push("macroargs", macroargs) + nomacro.functions[t[1][1]] = true + local r = lua(replacement) + nomacro.functions[t[1][1]] = nil + pop("macroargs") + return r elseif t[1].tag == "MethodStub" then -- method call if t[1][1].tag == "String" or t[1][1].tag == "Table" then return "("..lua(t[1][1]).."):"..lua(t[1][2], "Id").."("..lua(t, "_lhs", 2)..")" @@ -757,6 +793,20 @@ return function(code, ast, options) end, -- Id{ } Id = (t) + local macroargs = peek("macroargs") + if not nomacro.variables[t[1]] then + if macroargs and macroargs[t[1]] then -- replace with macro argument + nomacro.variables[t[1]] = true + local r = lua(macroargs[t[1]]) + nomacro.variables[t[1]] = nil + return r + elseif macros.variables[t[1]] ~= nil then -- replace with macro variable + nomacro.variables[t[1]] = true + local r = lua(macros.variables[t[1]]) + nomacro.variables[t[1]] = nil + return r + end + end return t[1] end, -- AttributeId{ ? } diff --git a/test/test.lua b/test/test.lua index 76bbcb9..0a5f635 100644 --- a/test/test.lua +++ b/test/test.lua @@ -151,6 +151,54 @@ return a #error("preprocessor should ignore long strings") ]]) +test("preprocessor macro remove function", [[ +#define("log(...)", "") +log("test") +return true +]], true) + +test("preprocessor macro replace function", [[ +#define("log(x)", "a = x") +log("test") +return a +]], "test") + +test("preprocessor macro identifier replace function", [[ +#define("test(x)", "x = 42") +test(hello) +return hello +]], 42) + +test("preprocessor macro replace function with vararg", [[ +#define("log(...)", "a, b, c = ...") +log(1, 2, 3) +assert(a == 1) +assert(b == 2) +assert(c == 3) +return true +]], true) + +test("preprocessor macro replace function with vararg and arg", [[ +#define("log(x, ...)", "a, b, c = x, ...") +log(1, 2, 3) +assert(a == 1) +assert(b == 2) +assert(c == 3) +return true +]], true) + +test("preprocessor macro replace variable", [[ +#define("a", "42") +return a +]], 42) + +test("preprocessor macro prevent recursive macro", [[ +#define("f(x)", "x") +local x = 42 +x = f(x) +return x +]], 42) + ---------------------- -- SYNTAX ADDITIONS -- ---------------------- From 6a1f7450156fb70ed6ac3841b2291ecd569271c0 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 7 Jun 2021 17:16:31 +0200 Subject: [PATCH 33/52] Update README --- README.md | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 805972c..c9215ba 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,13 @@ Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing L #import("lib.thing") -- static import #local debug or= false +#if debug +# define("log(...)", "print(...)") +#else +# define("log(...)", "") -- remove calls to log from the compiled code when debug is true +#end +log("example macro") -- preprocessor macros + local function calculate(toadd=25) -- default parameters local result = thing.do() result += toadd @@ -448,9 +455,34 @@ The preprocessor has access to the following variables: * ````include(filename)````: a function which copy the contents of the file _filename_ to the output. * ````write(...)````: write to the preprocessor output. For example, ````#write("hello()")```` will output ````hello()```` in the final file. * ```placeholder(name)```: if the variable _name_ is defined in the preprocessor environement, its content will be inserted here. +* ```define(identifier, replacement)```: define a macro. See below. * each arguments passed to the preprocessor is directly available in the environment. * and every standard Lua library. +#### Macros + +Using `define(identifier, replacement)` in the preprocessor, you can define macros. Both identifier and replacement are expected to be string containing Candran/Lua code. + +There are two types of macros: variables, which replace every instance of the given identifier with the replacement text; and functions, which will replace every call to this function with the replacement text, also replacing its arguments. The `...` will be replaced with every remaining argument. Macros can not be recursive. + +If the replacement text is empty, the macro will simply be removed from the compiled code. + +```lua +-- Variable macro +#define("x", 42) +print(x) -- 42 + +-- Function macros +#define("f(x)", "print(x)") +f(42) -- replaced with print(42) + +#define("log(s, ...)", "print(s..": ", ...)") +log("network", "error") -- network: error + +#define("debug()", "") +debug() -- not present in complied code +``` + Compile targets --------------- Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT, and Lua 5.1 compatible code. @@ -567,8 +599,8 @@ The table returned by _require("candran")_ gives you access to: ##### Compiler & preprocessor * ````candran.VERSION````: Candran's version string (e.g. `"0.10.0"`). -* ````candran.preprocess(code[, options])````: return the Candran code _code_, preprocessed with the _options_ options table; or nil, err in case of error. -* ````candran.compile(code[, options])````: return the Candran code compiled to Lua with the _options_ option table; or nil, err in case of error. +* ````candran.preprocess(code[, options])````: return the Candran code _code_, `macros` table. The code is preprocessed with the _options_ options table; `macros` is indented to be passed to `candran.compile` to apply the defined macros. In case of error, returns nil, error. +* ````candran.compile(code[, options[, macros]])````: return the Candran code compiled to Lua with the _options_ option table and the macros `macros` (table returned by the preprocessor); or nil, err in case of error. * ````candran.make(code[, options])````: return the Candran code, preprocessed and compiled with the _options_ options table; or nil, err in case of error. ##### Code loading helpers From 584dac17db836e39bd2f150d2280034c79538e63 Mon Sep 17 00:00:00 2001 From: Reuh Date: Mon, 7 Jun 2021 17:24:25 +0200 Subject: [PATCH 34/52] Typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9215ba..083e23a 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing L ````lua #import("lib.thing") -- static import -#local debug or= false +#local debug = false -#if debug +#if debug then # define("log(...)", "print(...)") #else # define("log(...)", "") -- remove calls to log from the compiled code when debug is true From 3c84d1fbdd5f017ddea60b5f89008843906902ea Mon Sep 17 00:00:00 2001 From: Reuh Date: Wed, 9 Jun 2021 13:43:52 +0200 Subject: [PATCH 35/52] Fix string.format errors on Lua 5.1 when using booleans or nil --- bin/can | 2 +- bin/canc | 2 +- candran.can | 4 ++-- candran.lua | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/can b/bin/can index cad0270..8c4cdc7 100644 --- a/bin/can +++ b/bin/can @@ -15,7 +15,7 @@ if args.help or args.h then print("Default options:") for opt, val in pairs(candran.default) do if type(val) == "string" then val = val:gsub("\n", "\\n") end - print((" %s=%q"):format(opt, val)) + print((" %s=%q"):format(opt, tostring(val))) end return end diff --git a/bin/canc b/bin/canc index b87cb8f..32265ef 100644 --- a/bin/canc +++ b/bin/canc @@ -23,7 +23,7 @@ if #arg < 1 or args.help or args.h then print("Default options:") for opt, val in pairs(candran.default) do if type(val) == "string" then val = val:gsub("\n", "\\n") end - print((" %s=%q"):format(opt, val)) + print((" %s=%q"):format(opt, tostring(val))) end return end diff --git a/candran.can b/candran.can index 57f115d..aa34258 100644 --- a/candran.can +++ b/candran.can @@ -203,7 +203,7 @@ local codeCache = {} function candran.loadfile(filepath, env, options) local f, err = io.open(filepath) if not f then - return nil, "cannot open %s":format(err) + return nil, "cannot open %s":format(tostring(err)) end local content = f:read("*a") f:close() @@ -321,7 +321,7 @@ function candran.searcher(modpath) if r then return r(modpath, filepath) else - error("error loading candran module '%s' from file '%s':\n\t%s":format(modpath, filepath, s), 0) + error("error loading candran module '%s' from file '%s':\n\t%s":format(modpath, filepath, tostring(s)), 0) end end, filepath end diff --git a/candran.lua b/candran.lua index 51a26ad..4512e48 100644 --- a/candran.lua +++ b/candran.lua @@ -6541,7 +6541,7 @@ local codeCache = {} -- candran.can:200 candran["loadfile"] = function(filepath, env, options) -- candran.can:203 local f, err = io["open"](filepath) -- candran.can:204 if not f then -- candran.can:205 -return nil, ("cannot open %s"):format(err) -- candran.can:206 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:206 end -- candran.can:206 local content = f:read("*a") -- candran.can:208 f:close() -- candran.can:209 @@ -6651,7 +6651,7 @@ if r then -- candran.can:321 return r(modpath, filepath) -- candran.can:322 else -- candran.can:322 error(("error loading candran module '%s' from file '%s':\ - %s"):format(modpath, filepath, s), 0) -- candran.can:324 + %s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:324 end -- candran.can:324 end, filepath -- candran.can:326 end -- candran.can:326 From 496a4ddafd4f4056c3fc6e8fda3a31b8f5341688 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 11 Jun 2021 13:46:31 +0200 Subject: [PATCH 36/52] Add support for macro replacement using Lua functions --- candran.can | 27 +- candran.lua | 9173 ++++++++++++++++++++++---------------------- compiler/lua54.can | 63 +- test/test.lua | 11 + 4 files changed, 4684 insertions(+), 4590 deletions(-) diff --git a/candran.can b/candran.can index b203ab1..cdb0ab7 100644 --- a/candran.can +++ b/candran.can @@ -150,24 +150,29 @@ function candran.preprocess(input, options={}) -- parse identifier local iast, ierr = parser.parsemacroidentifier(identifier, options.chunkname) if not iast then - return error("in macro identifier: %s":format(ierr)) + return error("in macro identifier: %s":format(tostring(ierr))) end -- parse replacement value - local rast, rerr = parser.parse(replacement, options.chunkname) - if not rast then - return error("in macro replacement: %s":format(rerr)) - end - -- when giving a single value as a replacement, bypass the implicit push - if #rast == 1 and rast[1].tag == "Push" and rast[1].implicit then - rast = rast[1][1] + if type(replacement) == "string" then + local rast, rerr = parser.parse(replacement, options.chunkname) + if not rast then + return error("in macro replacement: %s":format(tostring(rerr))) + end + -- when giving a single value as a replacement, bypass the implicit push + if #rast == 1 and rast[1].tag == "Push" and rast[1].implicit then + rast = rast[1][1] + end + replacement = rast + elseif type(replacement) ~= "function" then + error("bad argument #2 to 'define' (string or function expected)") end -- add macros if iast.tag == "MacroFunction" then - macros.functions[iast[1][1]] = { args = iast[2], replacement = rast } + macros.functions[iast[1][1]] = { args = iast[2], replacement = replacement } elseif iast.tag == "Id" then - macros.variables[iast[1]] = rast + macros.variables[iast[1]] = replacement else - error("invalid macro type %s":format(iast.tag)) + error("invalid macro type %s":format(tostring(iast.tag))) end end diff --git a/candran.lua b/candran.lua index fdcd523..6148a8f 100644 --- a/candran.lua +++ b/candran.lua @@ -144,1842 +144,1866 @@ package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua: local function _() -- ./candran/cmdline.lua:135 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -return function(code, ast, options, macros) -- ./compiler/lua54.can:5 -if macros == nil then macros = { -- ./compiler/lua54.can:5 -["functions"] = {}, -- ./compiler/lua54.can:5 -["variables"] = {} -- ./compiler/lua54.can:5 -} end -- ./compiler/lua54.can:5 -local lastInputPos = 1 -- ./compiler/lua54.can:7 -local prevLinePos = 1 -- ./compiler/lua54.can:8 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 -local lastLine = 1 -- ./compiler/lua54.can:10 -local indentLevel = 0 -- ./compiler/lua54.can:13 -local function newline() -- ./compiler/lua54.can:15 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 -if options["mapLines"] then -- ./compiler/lua54.can:17 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 +local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 +return function(code, ast, options, macros) -- ./compiler/lua54.can:7 +if macros == nil then macros = { -- ./compiler/lua54.can:7 +["functions"] = {}, -- ./compiler/lua54.can:7 +["variables"] = {} -- ./compiler/lua54.can:7 +} end -- ./compiler/lua54.can:7 +local lastInputPos = 1 -- ./compiler/lua54.can:9 +local prevLinePos = 1 -- ./compiler/lua54.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 +local lastLine = 1 -- ./compiler/lua54.can:12 +local indentLevel = 0 -- ./compiler/lua54.can:15 +local function newline() -- ./compiler/lua54.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 +if options["mapLines"] then -- ./compiler/lua54.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:19 -if source and line then -- ./compiler/lua54.can:21 -lastSource = source -- ./compiler/lua54.can:22 -lastLine = tonumber(line) -- ./compiler/lua54.can:23 -else -- ./compiler/lua54.can:23 +") -- ./compiler/lua54.can:21 +if source and line then -- ./compiler/lua54.can:23 +lastSource = source -- ./compiler/lua54.can:24 +lastLine = tonumber(line) -- ./compiler/lua54.can:25 +else -- ./compiler/lua54.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:25 -lastLine = lastLine + (1) -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -prevLinePos = lastInputPos -- ./compiler/lua54.can:30 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 -end -- ./compiler/lua54.can:32 -return r -- ./compiler/lua54.can:34 +") do -- ./compiler/lua54.can:27 +lastLine = lastLine + (1) -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +prevLinePos = lastInputPos -- ./compiler/lua54.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 end -- ./compiler/lua54.can:34 -local function indent() -- ./compiler/lua54.can:37 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 -return newline() -- ./compiler/lua54.can:39 -end -- ./compiler/lua54.can:39 -local function unindent() -- ./compiler/lua54.can:42 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 -return newline() -- ./compiler/lua54.can:44 -end -- ./compiler/lua54.can:44 -local states = { -- ./compiler/lua54.can:49 -["push"] = {}, -- ./compiler/lua54.can:50 -["destructuring"] = {}, -- ./compiler/lua54.can:51 -["scope"] = {}, -- ./compiler/lua54.can:52 -["macroargs"] = {} -- ./compiler/lua54.can:53 -} -- ./compiler/lua54.can:53 -local function push(name, state) -- ./compiler/lua54.can:56 -table["insert"](states[name], state) -- ./compiler/lua54.can:57 -return "" -- ./compiler/lua54.can:58 -end -- ./compiler/lua54.can:58 -local function pop(name) -- ./compiler/lua54.can:61 -table["remove"](states[name]) -- ./compiler/lua54.can:62 -return "" -- ./compiler/lua54.can:63 -end -- ./compiler/lua54.can:63 -local function set(name, state) -- ./compiler/lua54.can:66 -states[name][# states[name]] = state -- ./compiler/lua54.can:67 -return "" -- ./compiler/lua54.can:68 -end -- ./compiler/lua54.can:68 -local function peek(name) -- ./compiler/lua54.can:71 -return states[name][# states[name]] -- ./compiler/lua54.can:72 -end -- ./compiler/lua54.can:72 -local function var(name) -- ./compiler/lua54.can:77 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 -end -- ./compiler/lua54.can:78 -local function tmp() -- ./compiler/lua54.can:82 -local scope = peek("scope") -- ./compiler/lua54.can:83 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 -table["insert"](scope, var) -- ./compiler/lua54.can:85 -return var -- ./compiler/lua54.can:86 -end -- ./compiler/lua54.can:86 -local nomacro = { -- ./compiler/lua54.can:90 -["variables"] = {}, -- ./compiler/lua54.can:90 -["functions"] = {} -- ./compiler/lua54.can:90 -} -- ./compiler/lua54.can:90 -local required = {} -- ./compiler/lua54.can:93 -local requireStr = "" -- ./compiler/lua54.can:94 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 -if not required[req] then -- ./compiler/lua54.can:98 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 -required[req] = true -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -local loop = { -- ./compiler/lua54.can:105 -"While", -- ./compiler/lua54.can:105 -"Repeat", -- ./compiler/lua54.can:105 -"Fornum", -- ./compiler/lua54.can:105 -"Forin", -- ./compiler/lua54.can:105 -"WhileExpr", -- ./compiler/lua54.can:105 -"RepeatExpr", -- ./compiler/lua54.can:105 -"FornumExpr", -- ./compiler/lua54.can:105 -"ForinExpr" -- ./compiler/lua54.can:105 -} -- ./compiler/lua54.can:105 -local func = { -- ./compiler/lua54.can:106 -"Function", -- ./compiler/lua54.can:106 -"TableCompr", -- ./compiler/lua54.can:106 -"DoExpr", -- ./compiler/lua54.can:106 -"WhileExpr", -- ./compiler/lua54.can:106 -"RepeatExpr", -- ./compiler/lua54.can:106 -"IfExpr", -- ./compiler/lua54.can:106 -"FornumExpr", -- ./compiler/lua54.can:106 -"ForinExpr" -- ./compiler/lua54.can:106 -} -- ./compiler/lua54.can:106 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 -local tagsCheck = {} -- ./compiler/lua54.can:111 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 -tagsCheck[tag] = true -- ./compiler/lua54.can:113 -end -- ./compiler/lua54.can:113 -local nofollowCheck = {} -- ./compiler/lua54.can:115 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 -nofollowCheck[tag] = true -- ./compiler/lua54.can:117 -end -- ./compiler/lua54.can:117 -for _, node in ipairs(list) do -- ./compiler/lua54.can:119 -if type(node) == "table" then -- ./compiler/lua54.can:120 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 -return node -- ./compiler/lua54.can:122 -end -- ./compiler/lua54.can:122 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 -if r then -- ./compiler/lua54.can:126 -return r -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -return nil -- ./compiler/lua54.can:130 -end -- ./compiler/lua54.can:130 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 -local tagsCheck = {} -- ./compiler/lua54.can:136 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 -tagsCheck[tag] = true -- ./compiler/lua54.can:138 -end -- ./compiler/lua54.can:138 -local nofollowCheck = {} -- ./compiler/lua54.can:140 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 -nofollowCheck[tag] = true -- ./compiler/lua54.can:142 -end -- ./compiler/lua54.can:142 -local found = {} -- ./compiler/lua54.can:144 -for _, node in ipairs(list) do -- ./compiler/lua54.can:145 -if type(node) == "table" then -- ./compiler/lua54.can:146 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 -table["insert"](found, n) -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 -table["insert"](found, node) -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -return found -- ./compiler/lua54.can:157 -end -- ./compiler/lua54.can:157 -local function all(list, tags) -- ./compiler/lua54.can:161 -for _, node in ipairs(list) do -- ./compiler/lua54.can:162 -local ok = false -- ./compiler/lua54.can:163 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 -if node["tag"] == tag then -- ./compiler/lua54.can:165 -ok = true -- ./compiler/lua54.can:166 -break -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -if not ok then -- ./compiler/lua54.can:170 -return false -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -return true -- ./compiler/lua54.can:174 -end -- ./compiler/lua54.can:174 -local tags -- ./compiler/lua54.can:178 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 -end -- ./compiler/lua54.can:182 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +return r -- ./compiler/lua54.can:36 +end -- ./compiler/lua54.can:36 +local function indent() -- ./compiler/lua54.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 +return newline() -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local function unindent() -- ./compiler/lua54.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 +return newline() -- ./compiler/lua54.can:46 +end -- ./compiler/lua54.can:46 +local states = { -- ./compiler/lua54.can:51 +["push"] = {}, -- ./compiler/lua54.can:52 +["destructuring"] = {}, -- ./compiler/lua54.can:53 +["scope"] = {}, -- ./compiler/lua54.can:54 +["macroargs"] = {} -- ./compiler/lua54.can:55 +} -- ./compiler/lua54.can:55 +local function push(name, state) -- ./compiler/lua54.can:58 +table["insert"](states[name], state) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function pop(name) -- ./compiler/lua54.can:63 +table["remove"](states[name]) -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function set(name, state) -- ./compiler/lua54.can:68 +states[name][# states[name]] = state -- ./compiler/lua54.can:69 +return "" -- ./compiler/lua54.can:70 +end -- ./compiler/lua54.can:70 +local function peek(name) -- ./compiler/lua54.can:73 +return states[name][# states[name]] -- ./compiler/lua54.can:74 +end -- ./compiler/lua54.can:74 +local function var(name) -- ./compiler/lua54.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 +end -- ./compiler/lua54.can:80 +local function tmp() -- ./compiler/lua54.can:84 +local scope = peek("scope") -- ./compiler/lua54.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 +table["insert"](scope, var) -- ./compiler/lua54.can:87 +return var -- ./compiler/lua54.can:88 +end -- ./compiler/lua54.can:88 +local nomacro = { -- ./compiler/lua54.can:92 +["variables"] = {}, -- ./compiler/lua54.can:92 +["functions"] = {} -- ./compiler/lua54.can:92 +} -- ./compiler/lua54.can:92 +local required = {} -- ./compiler/lua54.can:95 +local requireStr = "" -- ./compiler/lua54.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 +if not required[req] then -- ./compiler/lua54.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 +required[req] = true -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +local loop = { -- ./compiler/lua54.can:107 +"While", -- ./compiler/lua54.can:107 +"Repeat", -- ./compiler/lua54.can:107 +"Fornum", -- ./compiler/lua54.can:107 +"Forin", -- ./compiler/lua54.can:107 +"WhileExpr", -- ./compiler/lua54.can:107 +"RepeatExpr", -- ./compiler/lua54.can:107 +"FornumExpr", -- ./compiler/lua54.can:107 +"ForinExpr" -- ./compiler/lua54.can:107 +} -- ./compiler/lua54.can:107 +local func = { -- ./compiler/lua54.can:108 +"Function", -- ./compiler/lua54.can:108 +"TableCompr", -- ./compiler/lua54.can:108 +"DoExpr", -- ./compiler/lua54.can:108 +"WhileExpr", -- ./compiler/lua54.can:108 +"RepeatExpr", -- ./compiler/lua54.can:108 +"IfExpr", -- ./compiler/lua54.can:108 +"FornumExpr", -- ./compiler/lua54.can:108 +"ForinExpr" -- ./compiler/lua54.can:108 +} -- ./compiler/lua54.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 +local tagsCheck = {} -- ./compiler/lua54.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 +tagsCheck[tag] = true -- ./compiler/lua54.can:115 +end -- ./compiler/lua54.can:115 +local nofollowCheck = {} -- ./compiler/lua54.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 +nofollowCheck[tag] = true -- ./compiler/lua54.can:119 +end -- ./compiler/lua54.can:119 +for _, node in ipairs(list) do -- ./compiler/lua54.can:121 +if type(node) == "table" then -- ./compiler/lua54.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 +return node -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 +if r then -- ./compiler/lua54.can:128 +return r -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +return nil -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 +local tagsCheck = {} -- ./compiler/lua54.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 +tagsCheck[tag] = true -- ./compiler/lua54.can:140 +end -- ./compiler/lua54.can:140 +local nofollowCheck = {} -- ./compiler/lua54.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 +nofollowCheck[tag] = true -- ./compiler/lua54.can:144 +end -- ./compiler/lua54.can:144 +local found = {} -- ./compiler/lua54.can:146 +for _, node in ipairs(list) do -- ./compiler/lua54.can:147 +if type(node) == "table" then -- ./compiler/lua54.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 +table["insert"](found, n) -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 +table["insert"](found, node) -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +return found -- ./compiler/lua54.can:159 +end -- ./compiler/lua54.can:159 +local function all(list, tags) -- ./compiler/lua54.can:163 +for _, node in ipairs(list) do -- ./compiler/lua54.can:164 +local ok = false -- ./compiler/lua54.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 +if node["tag"] == tag then -- ./compiler/lua54.can:167 +ok = true -- ./compiler/lua54.can:168 +break -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +if not ok then -- ./compiler/lua54.can:172 +return false -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +return true -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +local tags -- ./compiler/lua54.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 end -- ./compiler/lua54.can:184 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 -end -- ./compiler/lua54.can:189 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 -end -- ./compiler/lua54.can:192 -local CONTINUE_START = function() -- ./compiler/lua54.can:194 -return "do" .. indent() -- ./compiler/lua54.can:195 -end -- ./compiler/lua54.can:195 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 -end -- ./compiler/lua54.can:198 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 -local vars = {} -- ./compiler/lua54.can:201 -local values = {} -- ./compiler/lua54.can:202 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 -for _, v in ipairs(list) do -- ./compiler/lua54.can:204 -local var, val -- ./compiler/lua54.can:205 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 -var = v -- ./compiler/lua54.can:207 -val = { -- ./compiler/lua54.can:208 -["tag"] = "Index", -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "Id", -- ./compiler/lua54.can:208 -list["id"] -- ./compiler/lua54.can:208 -}, -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "String", -- ./compiler/lua54.can:208 -v[1] -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 -var = v[2] -- ./compiler/lua54.can:210 -val = { -- ./compiler/lua54.can:211 -["tag"] = "Index", -- ./compiler/lua54.can:211 -{ -- ./compiler/lua54.can:211 -["tag"] = "Id", -- ./compiler/lua54.can:211 -list["id"] -- ./compiler/lua54.can:211 -}, -- ./compiler/lua54.can:211 -v[1] -- ./compiler/lua54.can:211 -} -- ./compiler/lua54.can:211 -else -- ./compiler/lua54.can:211 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 -end -- ./compiler/lua54.can:213 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 -val = { -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["rightOp"], -- ./compiler/lua54.can:216 -var, -- ./compiler/lua54.can:216 -{ -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["leftOp"], -- ./compiler/lua54.can:216 -val, -- ./compiler/lua54.can:216 -var -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 +end -- ./compiler/lua54.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 +end -- ./compiler/lua54.can:194 +local CONTINUE_START = function() -- ./compiler/lua54.can:196 +return "do" .. indent() -- ./compiler/lua54.can:197 +end -- ./compiler/lua54.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 +end -- ./compiler/lua54.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 +local vars = {} -- ./compiler/lua54.can:203 +local values = {} -- ./compiler/lua54.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 +for _, v in ipairs(list) do -- ./compiler/lua54.can:206 +local var, val -- ./compiler/lua54.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 +var = v -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Index", -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Id", -- ./compiler/lua54.can:210 +list["id"] -- ./compiler/lua54.can:210 +}, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "String", -- ./compiler/lua54.can:210 +v[1] -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 +var = v[2] -- ./compiler/lua54.can:212 +val = { -- ./compiler/lua54.can:213 +["tag"] = "Index", -- ./compiler/lua54.can:213 +{ -- ./compiler/lua54.can:213 +["tag"] = "Id", -- ./compiler/lua54.can:213 +list["id"] -- ./compiler/lua54.can:213 +}, -- ./compiler/lua54.can:213 +v[1] -- ./compiler/lua54.can:213 +} -- ./compiler/lua54.can:213 +else -- ./compiler/lua54.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 +end -- ./compiler/lua54.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 val = { -- ./compiler/lua54.can:218 ["tag"] = "Op", -- ./compiler/lua54.can:218 destructured["rightOp"], -- ./compiler/lua54.can:218 var, -- ./compiler/lua54.can:218 -val -- ./compiler/lua54.can:218 +{ -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["leftOp"], -- ./compiler/lua54.can:218 +val, -- ./compiler/lua54.can:218 +var -- ./compiler/lua54.can:218 } -- ./compiler/lua54.can:218 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +} -- ./compiler/lua54.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 val = { -- ./compiler/lua54.can:220 ["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["leftOp"], -- ./compiler/lua54.can:220 -val, -- ./compiler/lua54.can:220 -var -- ./compiler/lua54.can:220 +destructured["rightOp"], -- ./compiler/lua54.can:220 +var, -- ./compiler/lua54.can:220 +val -- ./compiler/lua54.can:220 } -- ./compiler/lua54.can:220 -end -- ./compiler/lua54.can:220 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -if # vars > 0 then -- ./compiler/lua54.can:226 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 -if newlineAfter then -- ./compiler/lua54.can:228 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 -else -- ./compiler/lua54.can:229 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 -end -- ./compiler/lua54.can:231 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 +val = { -- ./compiler/lua54.can:222 +["tag"] = "Op", -- ./compiler/lua54.can:222 +destructured["leftOp"], -- ./compiler/lua54.can:222 +val, -- ./compiler/lua54.can:222 +var -- ./compiler/lua54.can:222 +} -- ./compiler/lua54.can:222 +end -- ./compiler/lua54.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +if # vars > 0 then -- ./compiler/lua54.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 +if newlineAfter then -- ./compiler/lua54.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 else -- ./compiler/lua54.can:231 -return "" -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -tags = setmetatable({ -- ./compiler/lua54.can:239 -["Block"] = function(t) -- ./compiler/lua54.can:241 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 -hasPush = false -- ./compiler/lua54.can:245 -end -- ./compiler/lua54.can:245 -local r = push("scope", {}) -- ./compiler/lua54.can:247 -if hasPush then -- ./compiler/lua54.can:248 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 -end -- ./compiler/lua54.can:249 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 -end -- ./compiler/lua54.can:252 -if t[# t] then -- ./compiler/lua54.can:254 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 -end -- ./compiler/lua54.can:255 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 -end -- ./compiler/lua54.can:258 -return r .. pop("scope") -- ./compiler/lua54.can:260 -end, -- ./compiler/lua54.can:260 -["Do"] = function(t) -- ./compiler/lua54.can:266 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 -end, -- ./compiler/lua54.can:267 -["Set"] = function(t) -- ./compiler/lua54.can:270 -local expr = t[# t] -- ./compiler/lua54.can:272 -local vars, values = {}, {} -- ./compiler/lua54.can:273 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 -else -- ./compiler/lua54.can:278 -table["insert"](vars, n) -- ./compiler/lua54.can:280 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 -local r = "" -- ./compiler/lua54.can:286 -if # vars > 0 then -- ./compiler/lua54.can:287 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 -end -- ./compiler/lua54.can:288 -if # destructuringVars > 0 then -- ./compiler/lua54.can:290 -local destructured = {} -- ./compiler/lua54.can:291 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 -end -- ./compiler/lua54.can:293 -return r -- ./compiler/lua54.can:295 -elseif # t == 4 then -- ./compiler/lua54.can:296 -if t[3] == "=" then -- ./compiler/lua54.can:297 -local r = "" -- ./compiler/lua54.can:298 -if # vars > 0 then -- ./compiler/lua54.can:299 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 -t[2], -- ./compiler/lua54.can:300 -vars[1], -- ./compiler/lua54.can:300 -{ -- ./compiler/lua54.can:300 -["tag"] = "Paren", -- ./compiler/lua54.can:300 -values[1] -- ./compiler/lua54.can:300 -} -- ./compiler/lua54.can:300 -}, "Op")) -- ./compiler/lua54.can:300 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 +end -- ./compiler/lua54.can:233 +else -- ./compiler/lua54.can:233 +return "" -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +tags = setmetatable({ -- ./compiler/lua54.can:241 +["Block"] = function(t) -- ./compiler/lua54.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 +hasPush = false -- ./compiler/lua54.can:247 +end -- ./compiler/lua54.can:247 +local r = push("scope", {}) -- ./compiler/lua54.can:249 +if hasPush then -- ./compiler/lua54.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 +end -- ./compiler/lua54.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 +end -- ./compiler/lua54.can:254 +if t[# t] then -- ./compiler/lua54.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 +end -- ./compiler/lua54.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 +end -- ./compiler/lua54.can:260 +return r .. pop("scope") -- ./compiler/lua54.can:262 +end, -- ./compiler/lua54.can:262 +["Do"] = function(t) -- ./compiler/lua54.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 +end, -- ./compiler/lua54.can:269 +["Set"] = function(t) -- ./compiler/lua54.can:272 +local expr = t[# t] -- ./compiler/lua54.can:274 +local vars, values = {}, {} -- ./compiler/lua54.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 +else -- ./compiler/lua54.can:280 +table["insert"](vars, n) -- ./compiler/lua54.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 +local r = "" -- ./compiler/lua54.can:288 +if # vars > 0 then -- ./compiler/lua54.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 +end -- ./compiler/lua54.can:290 +if # destructuringVars > 0 then -- ./compiler/lua54.can:292 +local destructured = {} -- ./compiler/lua54.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 +end -- ./compiler/lua54.can:295 +return r -- ./compiler/lua54.can:297 +elseif # t == 4 then -- ./compiler/lua54.can:298 +if t[3] == "=" then -- ./compiler/lua54.can:299 +local r = "" -- ./compiler/lua54.can:300 +if # vars > 0 then -- ./compiler/lua54.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 t[2], -- ./compiler/lua54.can:302 -vars[i], -- ./compiler/lua54.can:302 +vars[1], -- ./compiler/lua54.can:302 { -- ./compiler/lua54.can:302 ["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[i] -- ./compiler/lua54.can:302 +values[1] -- ./compiler/lua54.can:302 } -- ./compiler/lua54.can:302 }, "Op")) -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -if # destructuringVars > 0 then -- ./compiler/lua54.can:305 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 -end -- ./compiler/lua54.can:308 -return r -- ./compiler/lua54.can:310 -else -- ./compiler/lua54.can:310 -local r = "" -- ./compiler/lua54.can:312 -if # vars > 0 then -- ./compiler/lua54.can:313 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 -t[3], -- ./compiler/lua54.can:314 -{ -- ./compiler/lua54.can:314 -["tag"] = "Paren", -- ./compiler/lua54.can:314 -values[1] -- ./compiler/lua54.can:314 -}, -- ./compiler/lua54.can:314 -vars[1] -- ./compiler/lua54.can:314 -}, "Op")) -- ./compiler/lua54.can:314 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 +t[2], -- ./compiler/lua54.can:304 +vars[i], -- ./compiler/lua54.can:304 +{ -- ./compiler/lua54.can:304 +["tag"] = "Paren", -- ./compiler/lua54.can:304 +values[i] -- ./compiler/lua54.can:304 +} -- ./compiler/lua54.can:304 +}, "Op")) -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +if # destructuringVars > 0 then -- ./compiler/lua54.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +return r -- ./compiler/lua54.can:312 +else -- ./compiler/lua54.can:312 +local r = "" -- ./compiler/lua54.can:314 +if # vars > 0 then -- ./compiler/lua54.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 t[3], -- ./compiler/lua54.can:316 { -- ./compiler/lua54.can:316 ["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[i] -- ./compiler/lua54.can:316 +values[1] -- ./compiler/lua54.can:316 }, -- ./compiler/lua54.can:316 -vars[i] -- ./compiler/lua54.can:316 +vars[1] -- ./compiler/lua54.can:316 }, "Op")) -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -if # destructuringVars > 0 then -- ./compiler/lua54.can:319 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 -end -- ./compiler/lua54.can:322 -return r -- ./compiler/lua54.can:324 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 +t[3], -- ./compiler/lua54.can:318 +{ -- ./compiler/lua54.can:318 +["tag"] = "Paren", -- ./compiler/lua54.can:318 +values[i] -- ./compiler/lua54.can:318 +}, -- ./compiler/lua54.can:318 +vars[i] -- ./compiler/lua54.can:318 +}, "Op")) -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +if # destructuringVars > 0 then -- ./compiler/lua54.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 end -- ./compiler/lua54.can:324 -else -- ./compiler/lua54.can:324 -local r = "" -- ./compiler/lua54.can:327 -if # vars > 0 then -- ./compiler/lua54.can:328 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 -t[2], -- ./compiler/lua54.can:329 -vars[1], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Op", -- ./compiler/lua54.can:329 -t[4], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Paren", -- ./compiler/lua54.can:329 -values[1] -- ./compiler/lua54.can:329 -}, -- ./compiler/lua54.can:329 -vars[1] -- ./compiler/lua54.can:329 -} -- ./compiler/lua54.can:329 -}, "Op")) -- ./compiler/lua54.can:329 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:326 +end -- ./compiler/lua54.can:326 +else -- ./compiler/lua54.can:326 +local r = "" -- ./compiler/lua54.can:329 +if # vars > 0 then -- ./compiler/lua54.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 t[2], -- ./compiler/lua54.can:331 -vars[i], -- ./compiler/lua54.can:331 +vars[1], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Op", -- ./compiler/lua54.can:331 t[4], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[i] -- ./compiler/lua54.can:331 +values[1] -- ./compiler/lua54.can:331 }, -- ./compiler/lua54.can:331 -vars[i] -- ./compiler/lua54.can:331 +vars[1] -- ./compiler/lua54.can:331 } -- ./compiler/lua54.can:331 }, "Op")) -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -if # destructuringVars > 0 then -- ./compiler/lua54.can:334 -local destructured = { -- ./compiler/lua54.can:335 -["rightOp"] = t[2], -- ./compiler/lua54.can:335 -["leftOp"] = t[4] -- ./compiler/lua54.can:335 -} -- ./compiler/lua54.can:335 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 -end -- ./compiler/lua54.can:337 -return r -- ./compiler/lua54.can:339 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 +t[2], -- ./compiler/lua54.can:333 +vars[i], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Op", -- ./compiler/lua54.can:333 +t[4], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Paren", -- ./compiler/lua54.can:333 +values[i] -- ./compiler/lua54.can:333 +}, -- ./compiler/lua54.can:333 +vars[i] -- ./compiler/lua54.can:333 +} -- ./compiler/lua54.can:333 +}, "Op")) -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +if # destructuringVars > 0 then -- ./compiler/lua54.can:336 +local destructured = { -- ./compiler/lua54.can:337 +["rightOp"] = t[2], -- ./compiler/lua54.can:337 +["leftOp"] = t[4] -- ./compiler/lua54.can:337 +} -- ./compiler/lua54.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 end -- ./compiler/lua54.can:339 -end, -- ./compiler/lua54.can:339 -["While"] = function(t) -- ./compiler/lua54.can:343 -local r = "" -- ./compiler/lua54.can:344 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 -if # lets > 0 then -- ./compiler/lua54.can:347 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 -if # lets > 0 then -- ./compiler/lua54.can:354 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 -end -- ./compiler/lua54.can:355 -if hasContinue then -- ./compiler/lua54.can:357 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 -end -- ./compiler/lua54.can:358 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 -if hasContinue then -- ./compiler/lua54.can:361 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 -end -- ./compiler/lua54.can:362 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 -if # lets > 0 then -- ./compiler/lua54.can:365 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 -end -- ./compiler/lua54.can:367 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:341 +end -- ./compiler/lua54.can:341 +end, -- ./compiler/lua54.can:341 +["While"] = function(t) -- ./compiler/lua54.can:345 +local r = "" -- ./compiler/lua54.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 +if # lets > 0 then -- ./compiler/lua54.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 +if # lets > 0 then -- ./compiler/lua54.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 +end -- ./compiler/lua54.can:357 +if hasContinue then -- ./compiler/lua54.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 +end -- ./compiler/lua54.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 +if hasContinue then -- ./compiler/lua54.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 +end -- ./compiler/lua54.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 +if # lets > 0 then -- ./compiler/lua54.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 end -- ./compiler/lua54.can:369 -return r -- ./compiler/lua54.can:371 -end, -- ./compiler/lua54.can:371 -["Repeat"] = function(t) -- ./compiler/lua54.can:374 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 -local r = "repeat" .. indent() -- ./compiler/lua54.can:376 -if hasContinue then -- ./compiler/lua54.can:377 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 -end -- ./compiler/lua54.can:378 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 -if hasContinue then -- ./compiler/lua54.can:381 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 -end -- ./compiler/lua54.can:382 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 -return r -- ./compiler/lua54.can:385 -end, -- ./compiler/lua54.can:385 -["If"] = function(t) -- ./compiler/lua54.can:388 -local r = "" -- ./compiler/lua54.can:389 -local toClose = 0 -- ./compiler/lua54.can:390 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 -if # lets > 0 then -- ./compiler/lua54.can:392 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 -toClose = toClose + (1) -- ./compiler/lua54.can:394 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 -if # lets > 0 then -- ./compiler/lua54.can:402 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 -toClose = toClose + (1) -- ./compiler/lua54.can:404 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 -end -- ./compiler/lua54.can:406 -else -- ./compiler/lua54.can:406 -r = r .. ("else") -- ./compiler/lua54.can:409 -end -- ./compiler/lua54.can:409 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 +end -- ./compiler/lua54.can:371 +return r -- ./compiler/lua54.can:373 +end, -- ./compiler/lua54.can:373 +["Repeat"] = function(t) -- ./compiler/lua54.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 +local r = "repeat" .. indent() -- ./compiler/lua54.can:378 +if hasContinue then -- ./compiler/lua54.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 +end -- ./compiler/lua54.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 +if hasContinue then -- ./compiler/lua54.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 +end -- ./compiler/lua54.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 +return r -- ./compiler/lua54.can:387 +end, -- ./compiler/lua54.can:387 +["If"] = function(t) -- ./compiler/lua54.can:390 +local r = "" -- ./compiler/lua54.can:391 +local toClose = 0 -- ./compiler/lua54.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 +if # lets > 0 then -- ./compiler/lua54.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 +toClose = toClose + (1) -- ./compiler/lua54.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 +if # lets > 0 then -- ./compiler/lua54.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 +toClose = toClose + (1) -- ./compiler/lua54.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +else -- ./compiler/lua54.can:408 +r = r .. ("else") -- ./compiler/lua54.can:411 end -- ./compiler/lua54.can:411 -if # t % 2 == 1 then -- ./compiler/lua54.can:413 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 -end -- ./compiler/lua54.can:414 -r = r .. ("end") -- ./compiler/lua54.can:416 -for i = 1, toClose do -- ./compiler/lua54.can:417 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 -end -- ./compiler/lua54.can:418 -return r -- ./compiler/lua54.can:420 -end, -- ./compiler/lua54.can:420 -["Fornum"] = function(t) -- ./compiler/lua54.can:423 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 -if # t == 5 then -- ./compiler/lua54.can:425 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 -if hasContinue then -- ./compiler/lua54.can:428 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 -end -- ./compiler/lua54.can:429 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 -if hasContinue then -- ./compiler/lua54.can:432 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 -end -- ./compiler/lua54.can:433 -return r .. unindent() .. "end" -- ./compiler/lua54.can:435 -else -- ./compiler/lua54.can:435 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 -if hasContinue then -- ./compiler/lua54.can:439 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 -end -- ./compiler/lua54.can:440 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 -if hasContinue then -- ./compiler/lua54.can:443 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 -end -- ./compiler/lua54.can:444 -return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 +end -- ./compiler/lua54.can:413 +if # t % 2 == 1 then -- ./compiler/lua54.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 +end -- ./compiler/lua54.can:416 +r = r .. ("end") -- ./compiler/lua54.can:418 +for i = 1, toClose do -- ./compiler/lua54.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 +end -- ./compiler/lua54.can:420 +return r -- ./compiler/lua54.can:422 +end, -- ./compiler/lua54.can:422 +["Fornum"] = function(t) -- ./compiler/lua54.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 +if # t == 5 then -- ./compiler/lua54.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 +if hasContinue then -- ./compiler/lua54.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 +end -- ./compiler/lua54.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 +if hasContinue then -- ./compiler/lua54.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 +end -- ./compiler/lua54.can:435 +return r .. unindent() .. "end" -- ./compiler/lua54.can:437 +else -- ./compiler/lua54.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 +if hasContinue then -- ./compiler/lua54.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 +end -- ./compiler/lua54.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 +if hasContinue then -- ./compiler/lua54.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 end -- ./compiler/lua54.can:446 -end, -- ./compiler/lua54.can:446 -["Forin"] = function(t) -- ./compiler/lua54.can:450 -local destructured = {} -- ./compiler/lua54.can:451 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 -if hasContinue then -- ./compiler/lua54.can:454 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 -end -- ./compiler/lua54.can:455 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 -if hasContinue then -- ./compiler/lua54.can:458 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 -end -- ./compiler/lua54.can:459 -return r .. unindent() .. "end" -- ./compiler/lua54.can:461 -end, -- ./compiler/lua54.can:461 -["Local"] = function(t) -- ./compiler/lua54.can:464 -local destructured = {} -- ./compiler/lua54.can:465 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 -if t[2][1] then -- ./compiler/lua54.can:467 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 -end -- ./compiler/lua54.can:468 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 -end, -- ./compiler/lua54.can:470 -["Let"] = function(t) -- ./compiler/lua54.can:473 -local destructured = {} -- ./compiler/lua54.can:474 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 -local r = "local " .. nameList -- ./compiler/lua54.can:476 -if t[2][1] then -- ./compiler/lua54.can:477 -if all(t[2], { -- ./compiler/lua54.can:478 -"Nil", -- ./compiler/lua54.can:478 -"Dots", -- ./compiler/lua54.can:478 -"Boolean", -- ./compiler/lua54.can:478 -"Number", -- ./compiler/lua54.can:478 -"String" -- ./compiler/lua54.can:478 -}) then -- ./compiler/lua54.can:478 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 -else -- ./compiler/lua54.can:479 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 -end, -- ./compiler/lua54.can:484 -["Localrec"] = function(t) -- ./compiler/lua54.can:487 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 -end, -- ./compiler/lua54.can:488 -["Goto"] = function(t) -- ./compiler/lua54.can:491 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 -end, -- ./compiler/lua54.can:492 -["Label"] = function(t) -- ./compiler/lua54.can:495 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 -end, -- ./compiler/lua54.can:496 -["Return"] = function(t) -- ./compiler/lua54.can:499 -local push = peek("push") -- ./compiler/lua54.can:500 -if push then -- ./compiler/lua54.can:501 -local r = "" -- ./compiler/lua54.can:502 -for _, val in ipairs(t) do -- ./compiler/lua54.can:503 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 -end -- ./compiler/lua54.can:504 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 -else -- ./compiler/lua54.can:506 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 -end -- ./compiler/lua54.can:508 -end, -- ./compiler/lua54.can:508 -["Push"] = function(t) -- ./compiler/lua54.can:512 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 -r = "" -- ./compiler/lua54.can:514 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -if t[# t] then -- ./compiler/lua54.can:518 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 -else -- ./compiler/lua54.can:520 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -return r -- ./compiler/lua54.can:525 -end, -- ./compiler/lua54.can:525 -["Break"] = function() -- ./compiler/lua54.can:528 -return "break" -- ./compiler/lua54.can:529 -end, -- ./compiler/lua54.can:529 -["Continue"] = function() -- ./compiler/lua54.can:532 -return "goto " .. var("continue") -- ./compiler/lua54.can:533 -end, -- ./compiler/lua54.can:533 -["Nil"] = function() -- ./compiler/lua54.can:540 -return "nil" -- ./compiler/lua54.can:541 -end, -- ./compiler/lua54.can:541 -["Dots"] = function() -- ./compiler/lua54.can:544 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 -return r -- ./compiler/lua54.can:550 -else -- ./compiler/lua54.can:550 -return "..." -- ./compiler/lua54.can:552 -end -- ./compiler/lua54.can:552 -end, -- ./compiler/lua54.can:552 -["Boolean"] = function(t) -- ./compiler/lua54.can:556 -return tostring(t[1]) -- ./compiler/lua54.can:557 -end, -- ./compiler/lua54.can:557 -["Number"] = function(t) -- ./compiler/lua54.can:560 -return tostring(t[1]) -- ./compiler/lua54.can:561 -end, -- ./compiler/lua54.can:561 -["String"] = function(t) -- ./compiler/lua54.can:564 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 -end, -- ./compiler/lua54.can:565 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 -local r = "(" -- ./compiler/lua54.can:569 -local decl = {} -- ./compiler/lua54.can:570 -if t[1][1] then -- ./compiler/lua54.can:571 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 -r = r .. (id) -- ./compiler/lua54.can:577 -else -- ./compiler/lua54.can:577 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 -end -- ./compiler/lua54.can:579 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 -r = r .. (", " .. id) -- ./compiler/lua54.can:587 -else -- ./compiler/lua54.can:587 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 -r = r .. (d .. newline()) -- ./compiler/lua54.can:595 -end -- ./compiler/lua54.can:595 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 -end -- ./compiler/lua54.can:598 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 -if hasPush then -- ./compiler/lua54.can:601 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 -else -- ./compiler/lua54.can:602 -push("push", false) -- ./compiler/lua54.can:604 -end -- ./compiler/lua54.can:604 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 -end -- ./compiler/lua54.can:608 -pop("push") -- ./compiler/lua54.can:610 -return r .. unindent() .. "end" -- ./compiler/lua54.can:611 -end, -- ./compiler/lua54.can:611 -["Function"] = function(t) -- ./compiler/lua54.can:613 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 -end, -- ./compiler/lua54.can:614 -["Pair"] = function(t) -- ./compiler/lua54.can:617 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 -end, -- ./compiler/lua54.can:618 -["Table"] = function(t) -- ./compiler/lua54.can:620 -if # t == 0 then -- ./compiler/lua54.can:621 -return "{}" -- ./compiler/lua54.can:622 -elseif # t == 1 then -- ./compiler/lua54.can:623 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 -else -- ./compiler/lua54.can:624 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 -end -- ./compiler/lua54.can:626 -end, -- ./compiler/lua54.can:626 -["TableCompr"] = function(t) -- ./compiler/lua54.can:630 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 -end, -- ./compiler/lua54.can:631 -["Op"] = function(t) -- ./compiler/lua54.can:634 -local r -- ./compiler/lua54.can:635 -if # t == 2 then -- ./compiler/lua54.can:636 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 -else -- ./compiler/lua54.can:638 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 -end -- ./compiler/lua54.can:640 +return r .. unindent() .. "end" -- ./compiler/lua54.can:448 +end -- ./compiler/lua54.can:448 +end, -- ./compiler/lua54.can:448 +["Forin"] = function(t) -- ./compiler/lua54.can:452 +local destructured = {} -- ./compiler/lua54.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 +if hasContinue then -- ./compiler/lua54.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 +end -- ./compiler/lua54.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 +if hasContinue then -- ./compiler/lua54.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 +end -- ./compiler/lua54.can:461 +return r .. unindent() .. "end" -- ./compiler/lua54.can:463 +end, -- ./compiler/lua54.can:463 +["Local"] = function(t) -- ./compiler/lua54.can:466 +local destructured = {} -- ./compiler/lua54.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 +if t[2][1] then -- ./compiler/lua54.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 +end -- ./compiler/lua54.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 +end, -- ./compiler/lua54.can:472 +["Let"] = function(t) -- ./compiler/lua54.can:475 +local destructured = {} -- ./compiler/lua54.can:476 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 +local r = "local " .. nameList -- ./compiler/lua54.can:478 +if t[2][1] then -- ./compiler/lua54.can:479 +if all(t[2], { -- ./compiler/lua54.can:480 +"Nil", -- ./compiler/lua54.can:480 +"Dots", -- ./compiler/lua54.can:480 +"Boolean", -- ./compiler/lua54.can:480 +"Number", -- ./compiler/lua54.can:480 +"String" -- ./compiler/lua54.can:480 +}) then -- ./compiler/lua54.can:480 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +else -- ./compiler/lua54.can:481 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Localrec"] = function(t) -- ./compiler/lua54.can:489 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Goto"] = function(t) -- ./compiler/lua54.can:493 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 +end, -- ./compiler/lua54.can:494 +["Label"] = function(t) -- ./compiler/lua54.can:497 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 +end, -- ./compiler/lua54.can:498 +["Return"] = function(t) -- ./compiler/lua54.can:501 +local push = peek("push") -- ./compiler/lua54.can:502 +if push then -- ./compiler/lua54.can:503 +local r = "" -- ./compiler/lua54.can:504 +for _, val in ipairs(t) do -- ./compiler/lua54.can:505 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 +end -- ./compiler/lua54.can:506 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 +else -- ./compiler/lua54.can:508 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +end, -- ./compiler/lua54.can:510 +["Push"] = function(t) -- ./compiler/lua54.can:514 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 +r = "" -- ./compiler/lua54.can:516 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 +end -- ./compiler/lua54.can:518 +if t[# t] then -- ./compiler/lua54.can:520 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 +else -- ./compiler/lua54.can:522 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +return r -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Break"] = function() -- ./compiler/lua54.can:530 +return "break" -- ./compiler/lua54.can:531 +end, -- ./compiler/lua54.can:531 +["Continue"] = function() -- ./compiler/lua54.can:534 +return "goto " .. var("continue") -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Nil"] = function() -- ./compiler/lua54.can:542 +return "nil" -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Dots"] = function() -- ./compiler/lua54.can:546 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 +return r -- ./compiler/lua54.can:552 +else -- ./compiler/lua54.can:552 +return "..." -- ./compiler/lua54.can:554 +end -- ./compiler/lua54.can:554 +end, -- ./compiler/lua54.can:554 +["Boolean"] = function(t) -- ./compiler/lua54.can:558 +return tostring(t[1]) -- ./compiler/lua54.can:559 +end, -- ./compiler/lua54.can:559 +["Number"] = function(t) -- ./compiler/lua54.can:562 +return tostring(t[1]) -- ./compiler/lua54.can:563 +end, -- ./compiler/lua54.can:563 +["String"] = function(t) -- ./compiler/lua54.can:566 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 +end, -- ./compiler/lua54.can:567 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 +local r = "(" -- ./compiler/lua54.can:571 +local decl = {} -- ./compiler/lua54.can:572 +if t[1][1] then -- ./compiler/lua54.can:573 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 +r = r .. (id) -- ./compiler/lua54.can:579 +else -- ./compiler/lua54.can:579 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 +r = r .. (", " .. id) -- ./compiler/lua54.can:589 +else -- ./compiler/lua54.can:589 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 +r = r .. (d .. newline()) -- ./compiler/lua54.can:597 +end -- ./compiler/lua54.can:597 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 +end -- ./compiler/lua54.can:600 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 +if hasPush then -- ./compiler/lua54.can:603 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 +else -- ./compiler/lua54.can:604 +push("push", false) -- ./compiler/lua54.can:606 +end -- ./compiler/lua54.can:606 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 +end -- ./compiler/lua54.can:610 +pop("push") -- ./compiler/lua54.can:612 +return r .. unindent() .. "end" -- ./compiler/lua54.can:613 +end, -- ./compiler/lua54.can:613 +["Function"] = function(t) -- ./compiler/lua54.can:615 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 +end, -- ./compiler/lua54.can:616 +["Pair"] = function(t) -- ./compiler/lua54.can:619 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 +end, -- ./compiler/lua54.can:620 +["Table"] = function(t) -- ./compiler/lua54.can:622 +if # t == 0 then -- ./compiler/lua54.can:623 +return "{}" -- ./compiler/lua54.can:624 +elseif # t == 1 then -- ./compiler/lua54.can:625 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 +end -- ./compiler/lua54.can:628 +end, -- ./compiler/lua54.can:628 +["TableCompr"] = function(t) -- ./compiler/lua54.can:632 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 +end, -- ./compiler/lua54.can:633 +["Op"] = function(t) -- ./compiler/lua54.can:636 +local r -- ./compiler/lua54.can:637 +if # t == 2 then -- ./compiler/lua54.can:638 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 else -- ./compiler/lua54.can:640 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 -else -- ./compiler/lua54.can:644 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -return r -- ./compiler/lua54.can:649 -end, -- ./compiler/lua54.can:649 -["Paren"] = function(t) -- ./compiler/lua54.can:652 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 -end, -- ./compiler/lua54.can:653 -["MethodStub"] = function(t) -- ./compiler/lua54.can:656 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 -end, -- ./compiler/lua54.can:662 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 -end, -- ./compiler/lua54.can:672 -["LetExpr"] = function(t) -- ./compiler/lua54.can:679 -return lua(t[1][1]) -- ./compiler/lua54.can:680 -end, -- ./compiler/lua54.can:680 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 -local r = "(function()" .. indent() -- ./compiler/lua54.can:686 -if hasPush then -- ./compiler/lua54.can:687 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 -else -- ./compiler/lua54.can:688 -push("push", false) -- ./compiler/lua54.can:690 -end -- ./compiler/lua54.can:690 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 -if hasPush then -- ./compiler/lua54.can:693 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 -end -- ./compiler/lua54.can:694 -pop("push") -- ./compiler/lua54.can:696 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 -return r -- ./compiler/lua54.can:698 -end, -- ./compiler/lua54.can:698 -["DoExpr"] = function(t) -- ./compiler/lua54.can:701 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 -end -- ./compiler/lua54.can:703 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 -end, -- ./compiler/lua54.can:705 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 -end, -- ./compiler/lua54.can:709 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 -end, -- ./compiler/lua54.can:713 -["IfExpr"] = function(t) -- ./compiler/lua54.can:716 -for i = 2, # t do -- ./compiler/lua54.can:717 -local block = t[i] -- ./compiler/lua54.can:718 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 -end, -- ./compiler/lua54.can:723 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 -end, -- ./compiler/lua54.can:727 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 -end, -- ./compiler/lua54.can:731 -["Call"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 -local replacement = macro["replacement"] -- ./compiler/lua54.can:742 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 -macroargs["..."] = (function() -- ./compiler/lua54.can:746 -local self = {} -- ./compiler/lua54.can:746 -for j = i + 1, # t do -- ./compiler/lua54.can:746 -self[#self+1] = t[j] -- ./compiler/lua54.can:746 -end -- ./compiler/lua54.can:746 -return self -- ./compiler/lua54.can:746 -end)() -- ./compiler/lua54.can:746 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 -if t[i + 1] == nil then -- ./compiler/lua54.can:748 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 -end -- ./compiler/lua54.can:749 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 -else -- ./compiler/lua54.can:751 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -push("macroargs", macroargs) -- ./compiler/lua54.can:756 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 -local r = lua(replacement) -- ./compiler/lua54.can:758 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 -pop("macroargs") -- ./compiler/lua54.can:760 -return r -- ./compiler/lua54.can:761 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 -else -- ./compiler/lua54.can:764 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 -end -- ./compiler/lua54.can:766 -else -- ./compiler/lua54.can:766 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 +end -- ./compiler/lua54.can:642 +else -- ./compiler/lua54.can:642 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 +else -- ./compiler/lua54.can:646 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +return r -- ./compiler/lua54.can:651 +end, -- ./compiler/lua54.can:651 +["Paren"] = function(t) -- ./compiler/lua54.can:654 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 +end, -- ./compiler/lua54.can:655 +["MethodStub"] = function(t) -- ./compiler/lua54.can:658 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 +end, -- ./compiler/lua54.can:664 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 +end, -- ./compiler/lua54.can:674 +["LetExpr"] = function(t) -- ./compiler/lua54.can:681 +return lua(t[1][1]) -- ./compiler/lua54.can:682 +end, -- ./compiler/lua54.can:682 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 +local r = "(function()" .. indent() -- ./compiler/lua54.can:688 +if hasPush then -- ./compiler/lua54.can:689 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 +else -- ./compiler/lua54.can:690 +push("push", false) -- ./compiler/lua54.can:692 +end -- ./compiler/lua54.can:692 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 +if hasPush then -- ./compiler/lua54.can:695 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 +end -- ./compiler/lua54.can:696 +pop("push") -- ./compiler/lua54.can:698 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 +return r -- ./compiler/lua54.can:700 +end, -- ./compiler/lua54.can:700 +["DoExpr"] = function(t) -- ./compiler/lua54.can:703 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 +end -- ./compiler/lua54.can:705 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 +end, -- ./compiler/lua54.can:707 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 +end, -- ./compiler/lua54.can:711 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 +end, -- ./compiler/lua54.can:715 +["IfExpr"] = function(t) -- ./compiler/lua54.can:718 +for i = 2, # t do -- ./compiler/lua54.can:719 +local block = t[i] -- ./compiler/lua54.can:720 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 +end, -- ./compiler/lua54.can:725 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 +end, -- ./compiler/lua54.can:729 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["Call"] = function(t) -- ./compiler/lua54.can:739 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 +local replacement = macro["replacement"] -- ./compiler/lua54.can:744 +local r -- ./compiler/lua54.can:745 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 +if type(replacement) == "function" then -- ./compiler/lua54.can:747 +local args = {} -- ./compiler/lua54.can:748 +for i = 2, # t do -- ./compiler/lua54.can:749 +table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 +end -- ./compiler/lua54.can:750 +r = replacement(unpack(args)) -- ./compiler/lua54.can:752 +else -- ./compiler/lua54.can:752 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 +macroargs["..."] = (function() -- ./compiler/lua54.can:757 +local self = {} -- ./compiler/lua54.can:757 +for j = i + 1, # t do -- ./compiler/lua54.can:757 +self[#self+1] = t[j] -- ./compiler/lua54.can:757 +end -- ./compiler/lua54.can:757 +return self -- ./compiler/lua54.can:757 +end)() -- ./compiler/lua54.can:757 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 +if t[i + 1] == nil then -- ./compiler/lua54.can:759 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 +end -- ./compiler/lua54.can:760 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 +else -- ./compiler/lua54.can:762 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +push("macroargs", macroargs) -- ./compiler/lua54.can:767 +r = lua(replacement) -- ./compiler/lua54.can:768 +pop("macroargs") -- ./compiler/lua54.can:769 end -- ./compiler/lua54.can:769 -end, -- ./compiler/lua54.can:769 -["SafeCall"] = function(t) -- ./compiler/lua54.can:773 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 +return r -- ./compiler/lua54.can:772 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 else -- ./compiler/lua54.can:775 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 end -- ./compiler/lua54.can:777 -end, -- ./compiler/lua54.can:777 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 -if start == nil then start = 1 end -- ./compiler/lua54.can:782 -local r -- ./compiler/lua54.can:783 -if t[start] then -- ./compiler/lua54.can:784 -r = lua(t[start]) -- ./compiler/lua54.can:785 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 -end -- ./compiler/lua54.can:787 -else -- ./compiler/lua54.can:787 -r = "" -- ./compiler/lua54.can:790 -end -- ./compiler/lua54.can:790 -return r -- ./compiler/lua54.can:792 -end, -- ./compiler/lua54.can:792 -["Id"] = function(t) -- ./compiler/lua54.can:795 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 -local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:802 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 -local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 -return r -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -return t[1] -- ./compiler/lua54.can:810 -end, -- ./compiler/lua54.can:810 -["AttributeId"] = function(t) -- ./compiler/lua54.can:813 -if t[2] then -- ./compiler/lua54.can:814 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 -else -- ./compiler/lua54.can:815 -return t[1] -- ./compiler/lua54.can:817 -end -- ./compiler/lua54.can:817 -end, -- ./compiler/lua54.can:817 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 -if t["id"] then -- ./compiler/lua54.can:822 -return t["id"] -- ./compiler/lua54.can:823 -else -- ./compiler/lua54.can:823 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 -for j = 1, # t, 1 do -- ./compiler/lua54.can:827 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 -end -- ./compiler/lua54.can:828 -table["insert"](d, vars) -- ./compiler/lua54.can:830 -t["id"] = vars["id"] -- ./compiler/lua54.can:831 -return vars["id"] -- ./compiler/lua54.can:832 -end -- ./compiler/lua54.can:832 -end, -- ./compiler/lua54.can:832 -["Index"] = function(t) -- ./compiler/lua54.can:836 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 -else -- ./compiler/lua54.can:838 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 -end -- ./compiler/lua54.can:840 -end, -- ./compiler/lua54.can:840 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 -local l = {} -- ./compiler/lua54.can:846 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 -table["insert"](l, 1, t) -- ./compiler/lua54.can:848 -t = t[1] -- ./compiler/lua54.can:849 -end -- ./compiler/lua54.can:849 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 -for _, e in ipairs(l) do -- ./compiler/lua54.can:852 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 -else -- ./compiler/lua54.can:855 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 -return r -- ./compiler/lua54.can:861 -else -- ./compiler/lua54.can:861 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 -end -- ./compiler/lua54.can:863 -end, -- ./compiler/lua54.can:863 -["_opid"] = { -- ./compiler/lua54.can:868 -["add"] = "+", -- ./compiler/lua54.can:869 -["sub"] = "-", -- ./compiler/lua54.can:869 -["mul"] = "*", -- ./compiler/lua54.can:869 -["div"] = "/", -- ./compiler/lua54.can:869 -["idiv"] = "//", -- ./compiler/lua54.can:870 -["mod"] = "%", -- ./compiler/lua54.can:870 -["pow"] = "^", -- ./compiler/lua54.can:870 -["concat"] = "..", -- ./compiler/lua54.can:870 -["band"] = "&", -- ./compiler/lua54.can:871 -["bor"] = "|", -- ./compiler/lua54.can:871 -["bxor"] = "~", -- ./compiler/lua54.can:871 -["shl"] = "<<", -- ./compiler/lua54.can:871 -["shr"] = ">>", -- ./compiler/lua54.can:871 -["eq"] = "==", -- ./compiler/lua54.can:872 -["ne"] = "~=", -- ./compiler/lua54.can:872 -["lt"] = "<", -- ./compiler/lua54.can:872 -["gt"] = ">", -- ./compiler/lua54.can:872 -["le"] = "<=", -- ./compiler/lua54.can:872 -["ge"] = ">=", -- ./compiler/lua54.can:872 -["and"] = "and", -- ./compiler/lua54.can:873 -["or"] = "or", -- ./compiler/lua54.can:873 -["unm"] = "-", -- ./compiler/lua54.can:873 -["len"] = "#", -- ./compiler/lua54.can:873 -["bnot"] = "~", -- ./compiler/lua54.can:873 -["not"] = "not" -- ./compiler/lua54.can:873 -} -- ./compiler/lua54.can:873 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 -end }) -- ./compiler/lua54.can:877 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 -return requireStr .. code -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -local lua54 = _() or lua54 -- ./compiler/lua54.can:889 -package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:890 -local function _() -- ./compiler/lua54.can:893 -local function _() -- ./compiler/lua54.can:895 +else -- ./compiler/lua54.can:777 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 +end -- ./compiler/lua54.can:780 +end, -- ./compiler/lua54.can:780 +["SafeCall"] = function(t) -- ./compiler/lua54.can:784 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 +else -- ./compiler/lua54.can:786 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 +end -- ./compiler/lua54.can:788 +end, -- ./compiler/lua54.can:788 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 +if start == nil then start = 1 end -- ./compiler/lua54.can:793 +local r -- ./compiler/lua54.can:794 +if t[start] then -- ./compiler/lua54.can:795 +r = lua(t[start]) -- ./compiler/lua54.can:796 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 +end -- ./compiler/lua54.can:798 +else -- ./compiler/lua54.can:798 +r = "" -- ./compiler/lua54.can:801 +end -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:803 +end, -- ./compiler/lua54.can:803 +["Id"] = function(t) -- ./compiler/lua54.can:806 +local r = t[1] -- ./compiler/lua54.can:807 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 +r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 +local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 +if type(macro) == "function" then -- ./compiler/lua54.can:815 +r = macro() -- ./compiler/lua54.can:816 +else -- ./compiler/lua54.can:816 +r = lua(macro) -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 +end -- ./compiler/lua54.can:821 +return r -- ./compiler/lua54.can:823 +end, -- ./compiler/lua54.can:823 +["AttributeId"] = function(t) -- ./compiler/lua54.can:826 +if t[2] then -- ./compiler/lua54.can:827 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 +else -- ./compiler/lua54.can:828 +return t[1] -- ./compiler/lua54.can:830 +end -- ./compiler/lua54.can:830 +end, -- ./compiler/lua54.can:830 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 +if t["id"] then -- ./compiler/lua54.can:835 +return t["id"] -- ./compiler/lua54.can:836 +else -- ./compiler/lua54.can:836 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 +for j = 1, # t, 1 do -- ./compiler/lua54.can:840 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 +end -- ./compiler/lua54.can:841 +table["insert"](d, vars) -- ./compiler/lua54.can:843 +t["id"] = vars["id"] -- ./compiler/lua54.can:844 +return vars["id"] -- ./compiler/lua54.can:845 +end -- ./compiler/lua54.can:845 +end, -- ./compiler/lua54.can:845 +["Index"] = function(t) -- ./compiler/lua54.can:849 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 +else -- ./compiler/lua54.can:851 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 +end -- ./compiler/lua54.can:853 +end, -- ./compiler/lua54.can:853 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 +local l = {} -- ./compiler/lua54.can:859 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 +table["insert"](l, 1, t) -- ./compiler/lua54.can:861 +t = t[1] -- ./compiler/lua54.can:862 +end -- ./compiler/lua54.can:862 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 +for _, e in ipairs(l) do -- ./compiler/lua54.can:865 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 +else -- ./compiler/lua54.can:868 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 +return r -- ./compiler/lua54.can:874 +else -- ./compiler/lua54.can:874 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 +end -- ./compiler/lua54.can:876 +end, -- ./compiler/lua54.can:876 +["_opid"] = { -- ./compiler/lua54.can:881 +["add"] = "+", -- ./compiler/lua54.can:882 +["sub"] = "-", -- ./compiler/lua54.can:882 +["mul"] = "*", -- ./compiler/lua54.can:882 +["div"] = "/", -- ./compiler/lua54.can:882 +["idiv"] = "//", -- ./compiler/lua54.can:883 +["mod"] = "%", -- ./compiler/lua54.can:883 +["pow"] = "^", -- ./compiler/lua54.can:883 +["concat"] = "..", -- ./compiler/lua54.can:883 +["band"] = "&", -- ./compiler/lua54.can:884 +["bor"] = "|", -- ./compiler/lua54.can:884 +["bxor"] = "~", -- ./compiler/lua54.can:884 +["shl"] = "<<", -- ./compiler/lua54.can:884 +["shr"] = ">>", -- ./compiler/lua54.can:884 +["eq"] = "==", -- ./compiler/lua54.can:885 +["ne"] = "~=", -- ./compiler/lua54.can:885 +["lt"] = "<", -- ./compiler/lua54.can:885 +["gt"] = ">", -- ./compiler/lua54.can:885 +["le"] = "<=", -- ./compiler/lua54.can:885 +["ge"] = ">=", -- ./compiler/lua54.can:885 +["and"] = "and", -- ./compiler/lua54.can:886 +["or"] = "or", -- ./compiler/lua54.can:886 +["unm"] = "-", -- ./compiler/lua54.can:886 +["len"] = "#", -- ./compiler/lua54.can:886 +["bnot"] = "~", -- ./compiler/lua54.can:886 +["not"] = "not" -- ./compiler/lua54.can:886 +} -- ./compiler/lua54.can:886 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 +end }) -- ./compiler/lua54.can:890 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 +return requireStr .. code -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +local lua54 = _() or lua54 -- ./compiler/lua54.can:902 +package["loaded"]["compiler.lua54"] = lua54 or true -- ./compiler/lua54.can:903 +local function _() -- ./compiler/lua54.can:906 +local function _() -- ./compiler/lua54.can:908 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -return function(code, ast, options, macros) -- ./compiler/lua54.can:5 -if macros == nil then macros = { -- ./compiler/lua54.can:5 -["functions"] = {}, -- ./compiler/lua54.can:5 -["variables"] = {} -- ./compiler/lua54.can:5 -} end -- ./compiler/lua54.can:5 -local lastInputPos = 1 -- ./compiler/lua54.can:7 -local prevLinePos = 1 -- ./compiler/lua54.can:8 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 -local lastLine = 1 -- ./compiler/lua54.can:10 -local indentLevel = 0 -- ./compiler/lua54.can:13 -local function newline() -- ./compiler/lua54.can:15 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 -if options["mapLines"] then -- ./compiler/lua54.can:17 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 +local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 +return function(code, ast, options, macros) -- ./compiler/lua54.can:7 +if macros == nil then macros = { -- ./compiler/lua54.can:7 +["functions"] = {}, -- ./compiler/lua54.can:7 +["variables"] = {} -- ./compiler/lua54.can:7 +} end -- ./compiler/lua54.can:7 +local lastInputPos = 1 -- ./compiler/lua54.can:9 +local prevLinePos = 1 -- ./compiler/lua54.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 +local lastLine = 1 -- ./compiler/lua54.can:12 +local indentLevel = 0 -- ./compiler/lua54.can:15 +local function newline() -- ./compiler/lua54.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 +if options["mapLines"] then -- ./compiler/lua54.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:19 -if source and line then -- ./compiler/lua54.can:21 -lastSource = source -- ./compiler/lua54.can:22 -lastLine = tonumber(line) -- ./compiler/lua54.can:23 -else -- ./compiler/lua54.can:23 +") -- ./compiler/lua54.can:21 +if source and line then -- ./compiler/lua54.can:23 +lastSource = source -- ./compiler/lua54.can:24 +lastLine = tonumber(line) -- ./compiler/lua54.can:25 +else -- ./compiler/lua54.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:25 -lastLine = lastLine + (1) -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -prevLinePos = lastInputPos -- ./compiler/lua54.can:30 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 -end -- ./compiler/lua54.can:32 -return r -- ./compiler/lua54.can:34 +") do -- ./compiler/lua54.can:27 +lastLine = lastLine + (1) -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +prevLinePos = lastInputPos -- ./compiler/lua54.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 end -- ./compiler/lua54.can:34 -local function indent() -- ./compiler/lua54.can:37 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 -return newline() -- ./compiler/lua54.can:39 -end -- ./compiler/lua54.can:39 -local function unindent() -- ./compiler/lua54.can:42 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 -return newline() -- ./compiler/lua54.can:44 -end -- ./compiler/lua54.can:44 -local states = { -- ./compiler/lua54.can:49 -["push"] = {}, -- ./compiler/lua54.can:50 -["destructuring"] = {}, -- ./compiler/lua54.can:51 -["scope"] = {}, -- ./compiler/lua54.can:52 -["macroargs"] = {} -- ./compiler/lua54.can:53 -} -- ./compiler/lua54.can:53 -local function push(name, state) -- ./compiler/lua54.can:56 -table["insert"](states[name], state) -- ./compiler/lua54.can:57 -return "" -- ./compiler/lua54.can:58 -end -- ./compiler/lua54.can:58 -local function pop(name) -- ./compiler/lua54.can:61 -table["remove"](states[name]) -- ./compiler/lua54.can:62 -return "" -- ./compiler/lua54.can:63 -end -- ./compiler/lua54.can:63 -local function set(name, state) -- ./compiler/lua54.can:66 -states[name][# states[name]] = state -- ./compiler/lua54.can:67 -return "" -- ./compiler/lua54.can:68 -end -- ./compiler/lua54.can:68 -local function peek(name) -- ./compiler/lua54.can:71 -return states[name][# states[name]] -- ./compiler/lua54.can:72 -end -- ./compiler/lua54.can:72 -local function var(name) -- ./compiler/lua54.can:77 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 -end -- ./compiler/lua54.can:78 -local function tmp() -- ./compiler/lua54.can:82 -local scope = peek("scope") -- ./compiler/lua54.can:83 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 -table["insert"](scope, var) -- ./compiler/lua54.can:85 -return var -- ./compiler/lua54.can:86 -end -- ./compiler/lua54.can:86 -local nomacro = { -- ./compiler/lua54.can:90 -["variables"] = {}, -- ./compiler/lua54.can:90 -["functions"] = {} -- ./compiler/lua54.can:90 -} -- ./compiler/lua54.can:90 -local required = {} -- ./compiler/lua54.can:93 -local requireStr = "" -- ./compiler/lua54.can:94 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 -if not required[req] then -- ./compiler/lua54.can:98 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 -required[req] = true -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -local loop = { -- ./compiler/lua54.can:105 -"While", -- ./compiler/lua54.can:105 -"Repeat", -- ./compiler/lua54.can:105 -"Fornum", -- ./compiler/lua54.can:105 -"Forin", -- ./compiler/lua54.can:105 -"WhileExpr", -- ./compiler/lua54.can:105 -"RepeatExpr", -- ./compiler/lua54.can:105 -"FornumExpr", -- ./compiler/lua54.can:105 -"ForinExpr" -- ./compiler/lua54.can:105 -} -- ./compiler/lua54.can:105 -local func = { -- ./compiler/lua54.can:106 -"Function", -- ./compiler/lua54.can:106 -"TableCompr", -- ./compiler/lua54.can:106 -"DoExpr", -- ./compiler/lua54.can:106 -"WhileExpr", -- ./compiler/lua54.can:106 -"RepeatExpr", -- ./compiler/lua54.can:106 -"IfExpr", -- ./compiler/lua54.can:106 -"FornumExpr", -- ./compiler/lua54.can:106 -"ForinExpr" -- ./compiler/lua54.can:106 -} -- ./compiler/lua54.can:106 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 -local tagsCheck = {} -- ./compiler/lua54.can:111 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 -tagsCheck[tag] = true -- ./compiler/lua54.can:113 -end -- ./compiler/lua54.can:113 -local nofollowCheck = {} -- ./compiler/lua54.can:115 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 -nofollowCheck[tag] = true -- ./compiler/lua54.can:117 -end -- ./compiler/lua54.can:117 -for _, node in ipairs(list) do -- ./compiler/lua54.can:119 -if type(node) == "table" then -- ./compiler/lua54.can:120 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 -return node -- ./compiler/lua54.can:122 -end -- ./compiler/lua54.can:122 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 -if r then -- ./compiler/lua54.can:126 -return r -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -return nil -- ./compiler/lua54.can:130 -end -- ./compiler/lua54.can:130 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 -local tagsCheck = {} -- ./compiler/lua54.can:136 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 -tagsCheck[tag] = true -- ./compiler/lua54.can:138 -end -- ./compiler/lua54.can:138 -local nofollowCheck = {} -- ./compiler/lua54.can:140 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 -nofollowCheck[tag] = true -- ./compiler/lua54.can:142 -end -- ./compiler/lua54.can:142 -local found = {} -- ./compiler/lua54.can:144 -for _, node in ipairs(list) do -- ./compiler/lua54.can:145 -if type(node) == "table" then -- ./compiler/lua54.can:146 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 -table["insert"](found, n) -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 -table["insert"](found, node) -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -return found -- ./compiler/lua54.can:157 -end -- ./compiler/lua54.can:157 -local function all(list, tags) -- ./compiler/lua54.can:161 -for _, node in ipairs(list) do -- ./compiler/lua54.can:162 -local ok = false -- ./compiler/lua54.can:163 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 -if node["tag"] == tag then -- ./compiler/lua54.can:165 -ok = true -- ./compiler/lua54.can:166 -break -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -if not ok then -- ./compiler/lua54.can:170 -return false -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -return true -- ./compiler/lua54.can:174 -end -- ./compiler/lua54.can:174 -local tags -- ./compiler/lua54.can:178 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 -end -- ./compiler/lua54.can:182 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +return r -- ./compiler/lua54.can:36 +end -- ./compiler/lua54.can:36 +local function indent() -- ./compiler/lua54.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 +return newline() -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local function unindent() -- ./compiler/lua54.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 +return newline() -- ./compiler/lua54.can:46 +end -- ./compiler/lua54.can:46 +local states = { -- ./compiler/lua54.can:51 +["push"] = {}, -- ./compiler/lua54.can:52 +["destructuring"] = {}, -- ./compiler/lua54.can:53 +["scope"] = {}, -- ./compiler/lua54.can:54 +["macroargs"] = {} -- ./compiler/lua54.can:55 +} -- ./compiler/lua54.can:55 +local function push(name, state) -- ./compiler/lua54.can:58 +table["insert"](states[name], state) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function pop(name) -- ./compiler/lua54.can:63 +table["remove"](states[name]) -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function set(name, state) -- ./compiler/lua54.can:68 +states[name][# states[name]] = state -- ./compiler/lua54.can:69 +return "" -- ./compiler/lua54.can:70 +end -- ./compiler/lua54.can:70 +local function peek(name) -- ./compiler/lua54.can:73 +return states[name][# states[name]] -- ./compiler/lua54.can:74 +end -- ./compiler/lua54.can:74 +local function var(name) -- ./compiler/lua54.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 +end -- ./compiler/lua54.can:80 +local function tmp() -- ./compiler/lua54.can:84 +local scope = peek("scope") -- ./compiler/lua54.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 +table["insert"](scope, var) -- ./compiler/lua54.can:87 +return var -- ./compiler/lua54.can:88 +end -- ./compiler/lua54.can:88 +local nomacro = { -- ./compiler/lua54.can:92 +["variables"] = {}, -- ./compiler/lua54.can:92 +["functions"] = {} -- ./compiler/lua54.can:92 +} -- ./compiler/lua54.can:92 +local required = {} -- ./compiler/lua54.can:95 +local requireStr = "" -- ./compiler/lua54.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 +if not required[req] then -- ./compiler/lua54.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 +required[req] = true -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +local loop = { -- ./compiler/lua54.can:107 +"While", -- ./compiler/lua54.can:107 +"Repeat", -- ./compiler/lua54.can:107 +"Fornum", -- ./compiler/lua54.can:107 +"Forin", -- ./compiler/lua54.can:107 +"WhileExpr", -- ./compiler/lua54.can:107 +"RepeatExpr", -- ./compiler/lua54.can:107 +"FornumExpr", -- ./compiler/lua54.can:107 +"ForinExpr" -- ./compiler/lua54.can:107 +} -- ./compiler/lua54.can:107 +local func = { -- ./compiler/lua54.can:108 +"Function", -- ./compiler/lua54.can:108 +"TableCompr", -- ./compiler/lua54.can:108 +"DoExpr", -- ./compiler/lua54.can:108 +"WhileExpr", -- ./compiler/lua54.can:108 +"RepeatExpr", -- ./compiler/lua54.can:108 +"IfExpr", -- ./compiler/lua54.can:108 +"FornumExpr", -- ./compiler/lua54.can:108 +"ForinExpr" -- ./compiler/lua54.can:108 +} -- ./compiler/lua54.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 +local tagsCheck = {} -- ./compiler/lua54.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 +tagsCheck[tag] = true -- ./compiler/lua54.can:115 +end -- ./compiler/lua54.can:115 +local nofollowCheck = {} -- ./compiler/lua54.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 +nofollowCheck[tag] = true -- ./compiler/lua54.can:119 +end -- ./compiler/lua54.can:119 +for _, node in ipairs(list) do -- ./compiler/lua54.can:121 +if type(node) == "table" then -- ./compiler/lua54.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 +return node -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 +if r then -- ./compiler/lua54.can:128 +return r -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +return nil -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 +local tagsCheck = {} -- ./compiler/lua54.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 +tagsCheck[tag] = true -- ./compiler/lua54.can:140 +end -- ./compiler/lua54.can:140 +local nofollowCheck = {} -- ./compiler/lua54.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 +nofollowCheck[tag] = true -- ./compiler/lua54.can:144 +end -- ./compiler/lua54.can:144 +local found = {} -- ./compiler/lua54.can:146 +for _, node in ipairs(list) do -- ./compiler/lua54.can:147 +if type(node) == "table" then -- ./compiler/lua54.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 +table["insert"](found, n) -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 +table["insert"](found, node) -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +return found -- ./compiler/lua54.can:159 +end -- ./compiler/lua54.can:159 +local function all(list, tags) -- ./compiler/lua54.can:163 +for _, node in ipairs(list) do -- ./compiler/lua54.can:164 +local ok = false -- ./compiler/lua54.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 +if node["tag"] == tag then -- ./compiler/lua54.can:167 +ok = true -- ./compiler/lua54.can:168 +break -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +if not ok then -- ./compiler/lua54.can:172 +return false -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +return true -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +local tags -- ./compiler/lua54.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 end -- ./compiler/lua54.can:184 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 -end -- ./compiler/lua54.can:189 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 -end -- ./compiler/lua54.can:192 -local CONTINUE_START = function() -- ./compiler/lua54.can:194 -return "do" .. indent() -- ./compiler/lua54.can:195 -end -- ./compiler/lua54.can:195 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 -end -- ./compiler/lua54.can:198 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 -local vars = {} -- ./compiler/lua54.can:201 -local values = {} -- ./compiler/lua54.can:202 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 -for _, v in ipairs(list) do -- ./compiler/lua54.can:204 -local var, val -- ./compiler/lua54.can:205 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 -var = v -- ./compiler/lua54.can:207 -val = { -- ./compiler/lua54.can:208 -["tag"] = "Index", -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "Id", -- ./compiler/lua54.can:208 -list["id"] -- ./compiler/lua54.can:208 -}, -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "String", -- ./compiler/lua54.can:208 -v[1] -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 -var = v[2] -- ./compiler/lua54.can:210 -val = { -- ./compiler/lua54.can:211 -["tag"] = "Index", -- ./compiler/lua54.can:211 -{ -- ./compiler/lua54.can:211 -["tag"] = "Id", -- ./compiler/lua54.can:211 -list["id"] -- ./compiler/lua54.can:211 -}, -- ./compiler/lua54.can:211 -v[1] -- ./compiler/lua54.can:211 -} -- ./compiler/lua54.can:211 -else -- ./compiler/lua54.can:211 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 -end -- ./compiler/lua54.can:213 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 -val = { -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["rightOp"], -- ./compiler/lua54.can:216 -var, -- ./compiler/lua54.can:216 -{ -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["leftOp"], -- ./compiler/lua54.can:216 -val, -- ./compiler/lua54.can:216 -var -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 +end -- ./compiler/lua54.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 +end -- ./compiler/lua54.can:194 +local CONTINUE_START = function() -- ./compiler/lua54.can:196 +return "do" .. indent() -- ./compiler/lua54.can:197 +end -- ./compiler/lua54.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 +end -- ./compiler/lua54.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 +local vars = {} -- ./compiler/lua54.can:203 +local values = {} -- ./compiler/lua54.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 +for _, v in ipairs(list) do -- ./compiler/lua54.can:206 +local var, val -- ./compiler/lua54.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 +var = v -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Index", -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Id", -- ./compiler/lua54.can:210 +list["id"] -- ./compiler/lua54.can:210 +}, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "String", -- ./compiler/lua54.can:210 +v[1] -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 +var = v[2] -- ./compiler/lua54.can:212 +val = { -- ./compiler/lua54.can:213 +["tag"] = "Index", -- ./compiler/lua54.can:213 +{ -- ./compiler/lua54.can:213 +["tag"] = "Id", -- ./compiler/lua54.can:213 +list["id"] -- ./compiler/lua54.can:213 +}, -- ./compiler/lua54.can:213 +v[1] -- ./compiler/lua54.can:213 +} -- ./compiler/lua54.can:213 +else -- ./compiler/lua54.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 +end -- ./compiler/lua54.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 val = { -- ./compiler/lua54.can:218 ["tag"] = "Op", -- ./compiler/lua54.can:218 destructured["rightOp"], -- ./compiler/lua54.can:218 var, -- ./compiler/lua54.can:218 -val -- ./compiler/lua54.can:218 +{ -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["leftOp"], -- ./compiler/lua54.can:218 +val, -- ./compiler/lua54.can:218 +var -- ./compiler/lua54.can:218 } -- ./compiler/lua54.can:218 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +} -- ./compiler/lua54.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 val = { -- ./compiler/lua54.can:220 ["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["leftOp"], -- ./compiler/lua54.can:220 -val, -- ./compiler/lua54.can:220 -var -- ./compiler/lua54.can:220 +destructured["rightOp"], -- ./compiler/lua54.can:220 +var, -- ./compiler/lua54.can:220 +val -- ./compiler/lua54.can:220 } -- ./compiler/lua54.can:220 -end -- ./compiler/lua54.can:220 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -if # vars > 0 then -- ./compiler/lua54.can:226 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 -if newlineAfter then -- ./compiler/lua54.can:228 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 -else -- ./compiler/lua54.can:229 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 -end -- ./compiler/lua54.can:231 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 +val = { -- ./compiler/lua54.can:222 +["tag"] = "Op", -- ./compiler/lua54.can:222 +destructured["leftOp"], -- ./compiler/lua54.can:222 +val, -- ./compiler/lua54.can:222 +var -- ./compiler/lua54.can:222 +} -- ./compiler/lua54.can:222 +end -- ./compiler/lua54.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +if # vars > 0 then -- ./compiler/lua54.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 +if newlineAfter then -- ./compiler/lua54.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 else -- ./compiler/lua54.can:231 -return "" -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -tags = setmetatable({ -- ./compiler/lua54.can:239 -["Block"] = function(t) -- ./compiler/lua54.can:241 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 -hasPush = false -- ./compiler/lua54.can:245 -end -- ./compiler/lua54.can:245 -local r = push("scope", {}) -- ./compiler/lua54.can:247 -if hasPush then -- ./compiler/lua54.can:248 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 -end -- ./compiler/lua54.can:249 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 -end -- ./compiler/lua54.can:252 -if t[# t] then -- ./compiler/lua54.can:254 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 -end -- ./compiler/lua54.can:255 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 -end -- ./compiler/lua54.can:258 -return r .. pop("scope") -- ./compiler/lua54.can:260 -end, -- ./compiler/lua54.can:260 -["Do"] = function(t) -- ./compiler/lua54.can:266 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 -end, -- ./compiler/lua54.can:267 -["Set"] = function(t) -- ./compiler/lua54.can:270 -local expr = t[# t] -- ./compiler/lua54.can:272 -local vars, values = {}, {} -- ./compiler/lua54.can:273 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 -else -- ./compiler/lua54.can:278 -table["insert"](vars, n) -- ./compiler/lua54.can:280 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 -local r = "" -- ./compiler/lua54.can:286 -if # vars > 0 then -- ./compiler/lua54.can:287 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 -end -- ./compiler/lua54.can:288 -if # destructuringVars > 0 then -- ./compiler/lua54.can:290 -local destructured = {} -- ./compiler/lua54.can:291 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 -end -- ./compiler/lua54.can:293 -return r -- ./compiler/lua54.can:295 -elseif # t == 4 then -- ./compiler/lua54.can:296 -if t[3] == "=" then -- ./compiler/lua54.can:297 -local r = "" -- ./compiler/lua54.can:298 -if # vars > 0 then -- ./compiler/lua54.can:299 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 -t[2], -- ./compiler/lua54.can:300 -vars[1], -- ./compiler/lua54.can:300 -{ -- ./compiler/lua54.can:300 -["tag"] = "Paren", -- ./compiler/lua54.can:300 -values[1] -- ./compiler/lua54.can:300 -} -- ./compiler/lua54.can:300 -}, "Op")) -- ./compiler/lua54.can:300 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 +end -- ./compiler/lua54.can:233 +else -- ./compiler/lua54.can:233 +return "" -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +tags = setmetatable({ -- ./compiler/lua54.can:241 +["Block"] = function(t) -- ./compiler/lua54.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 +hasPush = false -- ./compiler/lua54.can:247 +end -- ./compiler/lua54.can:247 +local r = push("scope", {}) -- ./compiler/lua54.can:249 +if hasPush then -- ./compiler/lua54.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 +end -- ./compiler/lua54.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 +end -- ./compiler/lua54.can:254 +if t[# t] then -- ./compiler/lua54.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 +end -- ./compiler/lua54.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 +end -- ./compiler/lua54.can:260 +return r .. pop("scope") -- ./compiler/lua54.can:262 +end, -- ./compiler/lua54.can:262 +["Do"] = function(t) -- ./compiler/lua54.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 +end, -- ./compiler/lua54.can:269 +["Set"] = function(t) -- ./compiler/lua54.can:272 +local expr = t[# t] -- ./compiler/lua54.can:274 +local vars, values = {}, {} -- ./compiler/lua54.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 +else -- ./compiler/lua54.can:280 +table["insert"](vars, n) -- ./compiler/lua54.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 +local r = "" -- ./compiler/lua54.can:288 +if # vars > 0 then -- ./compiler/lua54.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 +end -- ./compiler/lua54.can:290 +if # destructuringVars > 0 then -- ./compiler/lua54.can:292 +local destructured = {} -- ./compiler/lua54.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 +end -- ./compiler/lua54.can:295 +return r -- ./compiler/lua54.can:297 +elseif # t == 4 then -- ./compiler/lua54.can:298 +if t[3] == "=" then -- ./compiler/lua54.can:299 +local r = "" -- ./compiler/lua54.can:300 +if # vars > 0 then -- ./compiler/lua54.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 t[2], -- ./compiler/lua54.can:302 -vars[i], -- ./compiler/lua54.can:302 +vars[1], -- ./compiler/lua54.can:302 { -- ./compiler/lua54.can:302 ["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[i] -- ./compiler/lua54.can:302 +values[1] -- ./compiler/lua54.can:302 } -- ./compiler/lua54.can:302 }, "Op")) -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -if # destructuringVars > 0 then -- ./compiler/lua54.can:305 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 -end -- ./compiler/lua54.can:308 -return r -- ./compiler/lua54.can:310 -else -- ./compiler/lua54.can:310 -local r = "" -- ./compiler/lua54.can:312 -if # vars > 0 then -- ./compiler/lua54.can:313 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 -t[3], -- ./compiler/lua54.can:314 -{ -- ./compiler/lua54.can:314 -["tag"] = "Paren", -- ./compiler/lua54.can:314 -values[1] -- ./compiler/lua54.can:314 -}, -- ./compiler/lua54.can:314 -vars[1] -- ./compiler/lua54.can:314 -}, "Op")) -- ./compiler/lua54.can:314 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 +t[2], -- ./compiler/lua54.can:304 +vars[i], -- ./compiler/lua54.can:304 +{ -- ./compiler/lua54.can:304 +["tag"] = "Paren", -- ./compiler/lua54.can:304 +values[i] -- ./compiler/lua54.can:304 +} -- ./compiler/lua54.can:304 +}, "Op")) -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +if # destructuringVars > 0 then -- ./compiler/lua54.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +return r -- ./compiler/lua54.can:312 +else -- ./compiler/lua54.can:312 +local r = "" -- ./compiler/lua54.can:314 +if # vars > 0 then -- ./compiler/lua54.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 t[3], -- ./compiler/lua54.can:316 { -- ./compiler/lua54.can:316 ["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[i] -- ./compiler/lua54.can:316 +values[1] -- ./compiler/lua54.can:316 }, -- ./compiler/lua54.can:316 -vars[i] -- ./compiler/lua54.can:316 +vars[1] -- ./compiler/lua54.can:316 }, "Op")) -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -if # destructuringVars > 0 then -- ./compiler/lua54.can:319 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 -end -- ./compiler/lua54.can:322 -return r -- ./compiler/lua54.can:324 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 +t[3], -- ./compiler/lua54.can:318 +{ -- ./compiler/lua54.can:318 +["tag"] = "Paren", -- ./compiler/lua54.can:318 +values[i] -- ./compiler/lua54.can:318 +}, -- ./compiler/lua54.can:318 +vars[i] -- ./compiler/lua54.can:318 +}, "Op")) -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +if # destructuringVars > 0 then -- ./compiler/lua54.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 end -- ./compiler/lua54.can:324 -else -- ./compiler/lua54.can:324 -local r = "" -- ./compiler/lua54.can:327 -if # vars > 0 then -- ./compiler/lua54.can:328 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 -t[2], -- ./compiler/lua54.can:329 -vars[1], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Op", -- ./compiler/lua54.can:329 -t[4], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Paren", -- ./compiler/lua54.can:329 -values[1] -- ./compiler/lua54.can:329 -}, -- ./compiler/lua54.can:329 -vars[1] -- ./compiler/lua54.can:329 -} -- ./compiler/lua54.can:329 -}, "Op")) -- ./compiler/lua54.can:329 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:326 +end -- ./compiler/lua54.can:326 +else -- ./compiler/lua54.can:326 +local r = "" -- ./compiler/lua54.can:329 +if # vars > 0 then -- ./compiler/lua54.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 t[2], -- ./compiler/lua54.can:331 -vars[i], -- ./compiler/lua54.can:331 +vars[1], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Op", -- ./compiler/lua54.can:331 t[4], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[i] -- ./compiler/lua54.can:331 +values[1] -- ./compiler/lua54.can:331 }, -- ./compiler/lua54.can:331 -vars[i] -- ./compiler/lua54.can:331 +vars[1] -- ./compiler/lua54.can:331 } -- ./compiler/lua54.can:331 }, "Op")) -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -if # destructuringVars > 0 then -- ./compiler/lua54.can:334 -local destructured = { -- ./compiler/lua54.can:335 -["rightOp"] = t[2], -- ./compiler/lua54.can:335 -["leftOp"] = t[4] -- ./compiler/lua54.can:335 -} -- ./compiler/lua54.can:335 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 -end -- ./compiler/lua54.can:337 -return r -- ./compiler/lua54.can:339 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 +t[2], -- ./compiler/lua54.can:333 +vars[i], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Op", -- ./compiler/lua54.can:333 +t[4], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Paren", -- ./compiler/lua54.can:333 +values[i] -- ./compiler/lua54.can:333 +}, -- ./compiler/lua54.can:333 +vars[i] -- ./compiler/lua54.can:333 +} -- ./compiler/lua54.can:333 +}, "Op")) -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +if # destructuringVars > 0 then -- ./compiler/lua54.can:336 +local destructured = { -- ./compiler/lua54.can:337 +["rightOp"] = t[2], -- ./compiler/lua54.can:337 +["leftOp"] = t[4] -- ./compiler/lua54.can:337 +} -- ./compiler/lua54.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 end -- ./compiler/lua54.can:339 -end, -- ./compiler/lua54.can:339 -["While"] = function(t) -- ./compiler/lua54.can:343 -local r = "" -- ./compiler/lua54.can:344 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 -if # lets > 0 then -- ./compiler/lua54.can:347 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 -if # lets > 0 then -- ./compiler/lua54.can:354 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 -end -- ./compiler/lua54.can:355 -if hasContinue then -- ./compiler/lua54.can:357 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 -end -- ./compiler/lua54.can:358 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 -if hasContinue then -- ./compiler/lua54.can:361 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 -end -- ./compiler/lua54.can:362 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 -if # lets > 0 then -- ./compiler/lua54.can:365 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 -end -- ./compiler/lua54.can:367 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:341 +end -- ./compiler/lua54.can:341 +end, -- ./compiler/lua54.can:341 +["While"] = function(t) -- ./compiler/lua54.can:345 +local r = "" -- ./compiler/lua54.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 +if # lets > 0 then -- ./compiler/lua54.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 +if # lets > 0 then -- ./compiler/lua54.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 +end -- ./compiler/lua54.can:357 +if hasContinue then -- ./compiler/lua54.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 +end -- ./compiler/lua54.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 +if hasContinue then -- ./compiler/lua54.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 +end -- ./compiler/lua54.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 +if # lets > 0 then -- ./compiler/lua54.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 end -- ./compiler/lua54.can:369 -return r -- ./compiler/lua54.can:371 -end, -- ./compiler/lua54.can:371 -["Repeat"] = function(t) -- ./compiler/lua54.can:374 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 -local r = "repeat" .. indent() -- ./compiler/lua54.can:376 -if hasContinue then -- ./compiler/lua54.can:377 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 -end -- ./compiler/lua54.can:378 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 -if hasContinue then -- ./compiler/lua54.can:381 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 -end -- ./compiler/lua54.can:382 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 -return r -- ./compiler/lua54.can:385 -end, -- ./compiler/lua54.can:385 -["If"] = function(t) -- ./compiler/lua54.can:388 -local r = "" -- ./compiler/lua54.can:389 -local toClose = 0 -- ./compiler/lua54.can:390 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 -if # lets > 0 then -- ./compiler/lua54.can:392 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 -toClose = toClose + (1) -- ./compiler/lua54.can:394 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 -if # lets > 0 then -- ./compiler/lua54.can:402 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 -toClose = toClose + (1) -- ./compiler/lua54.can:404 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 -end -- ./compiler/lua54.can:406 -else -- ./compiler/lua54.can:406 -r = r .. ("else") -- ./compiler/lua54.can:409 -end -- ./compiler/lua54.can:409 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 +end -- ./compiler/lua54.can:371 +return r -- ./compiler/lua54.can:373 +end, -- ./compiler/lua54.can:373 +["Repeat"] = function(t) -- ./compiler/lua54.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 +local r = "repeat" .. indent() -- ./compiler/lua54.can:378 +if hasContinue then -- ./compiler/lua54.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 +end -- ./compiler/lua54.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 +if hasContinue then -- ./compiler/lua54.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 +end -- ./compiler/lua54.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 +return r -- ./compiler/lua54.can:387 +end, -- ./compiler/lua54.can:387 +["If"] = function(t) -- ./compiler/lua54.can:390 +local r = "" -- ./compiler/lua54.can:391 +local toClose = 0 -- ./compiler/lua54.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 +if # lets > 0 then -- ./compiler/lua54.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 +toClose = toClose + (1) -- ./compiler/lua54.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 +if # lets > 0 then -- ./compiler/lua54.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 +toClose = toClose + (1) -- ./compiler/lua54.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +else -- ./compiler/lua54.can:408 +r = r .. ("else") -- ./compiler/lua54.can:411 end -- ./compiler/lua54.can:411 -if # t % 2 == 1 then -- ./compiler/lua54.can:413 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 -end -- ./compiler/lua54.can:414 -r = r .. ("end") -- ./compiler/lua54.can:416 -for i = 1, toClose do -- ./compiler/lua54.can:417 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 -end -- ./compiler/lua54.can:418 -return r -- ./compiler/lua54.can:420 -end, -- ./compiler/lua54.can:420 -["Fornum"] = function(t) -- ./compiler/lua54.can:423 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 -if # t == 5 then -- ./compiler/lua54.can:425 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 -if hasContinue then -- ./compiler/lua54.can:428 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 -end -- ./compiler/lua54.can:429 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 -if hasContinue then -- ./compiler/lua54.can:432 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 -end -- ./compiler/lua54.can:433 -return r .. unindent() .. "end" -- ./compiler/lua54.can:435 -else -- ./compiler/lua54.can:435 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 -if hasContinue then -- ./compiler/lua54.can:439 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 -end -- ./compiler/lua54.can:440 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 -if hasContinue then -- ./compiler/lua54.can:443 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 -end -- ./compiler/lua54.can:444 -return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 +end -- ./compiler/lua54.can:413 +if # t % 2 == 1 then -- ./compiler/lua54.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 +end -- ./compiler/lua54.can:416 +r = r .. ("end") -- ./compiler/lua54.can:418 +for i = 1, toClose do -- ./compiler/lua54.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 +end -- ./compiler/lua54.can:420 +return r -- ./compiler/lua54.can:422 +end, -- ./compiler/lua54.can:422 +["Fornum"] = function(t) -- ./compiler/lua54.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 +if # t == 5 then -- ./compiler/lua54.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 +if hasContinue then -- ./compiler/lua54.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 +end -- ./compiler/lua54.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 +if hasContinue then -- ./compiler/lua54.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 +end -- ./compiler/lua54.can:435 +return r .. unindent() .. "end" -- ./compiler/lua54.can:437 +else -- ./compiler/lua54.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 +if hasContinue then -- ./compiler/lua54.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 +end -- ./compiler/lua54.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 +if hasContinue then -- ./compiler/lua54.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 end -- ./compiler/lua54.can:446 -end, -- ./compiler/lua54.can:446 -["Forin"] = function(t) -- ./compiler/lua54.can:450 -local destructured = {} -- ./compiler/lua54.can:451 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 -if hasContinue then -- ./compiler/lua54.can:454 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 -end -- ./compiler/lua54.can:455 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 -if hasContinue then -- ./compiler/lua54.can:458 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 -end -- ./compiler/lua54.can:459 -return r .. unindent() .. "end" -- ./compiler/lua54.can:461 -end, -- ./compiler/lua54.can:461 -["Local"] = function(t) -- ./compiler/lua54.can:464 -local destructured = {} -- ./compiler/lua54.can:465 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 -if t[2][1] then -- ./compiler/lua54.can:467 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 -end -- ./compiler/lua54.can:468 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 -end, -- ./compiler/lua54.can:470 -["Let"] = function(t) -- ./compiler/lua54.can:473 -local destructured = {} -- ./compiler/lua54.can:474 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 -local r = "local " .. nameList -- ./compiler/lua54.can:476 -if t[2][1] then -- ./compiler/lua54.can:477 -if all(t[2], { -- ./compiler/lua54.can:478 -"Nil", -- ./compiler/lua54.can:478 -"Dots", -- ./compiler/lua54.can:478 -"Boolean", -- ./compiler/lua54.can:478 -"Number", -- ./compiler/lua54.can:478 -"String" -- ./compiler/lua54.can:478 -}) then -- ./compiler/lua54.can:478 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 -else -- ./compiler/lua54.can:479 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 -end, -- ./compiler/lua54.can:484 -["Localrec"] = function(t) -- ./compiler/lua54.can:487 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 -end, -- ./compiler/lua54.can:488 -["Goto"] = function(t) -- ./compiler/lua54.can:491 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 -end, -- ./compiler/lua54.can:492 -["Label"] = function(t) -- ./compiler/lua54.can:495 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 -end, -- ./compiler/lua54.can:496 -["Return"] = function(t) -- ./compiler/lua54.can:499 -local push = peek("push") -- ./compiler/lua54.can:500 -if push then -- ./compiler/lua54.can:501 -local r = "" -- ./compiler/lua54.can:502 -for _, val in ipairs(t) do -- ./compiler/lua54.can:503 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 -end -- ./compiler/lua54.can:504 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 -else -- ./compiler/lua54.can:506 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 -end -- ./compiler/lua54.can:508 -end, -- ./compiler/lua54.can:508 -["Push"] = function(t) -- ./compiler/lua54.can:512 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 -r = "" -- ./compiler/lua54.can:514 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -if t[# t] then -- ./compiler/lua54.can:518 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 -else -- ./compiler/lua54.can:520 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -return r -- ./compiler/lua54.can:525 -end, -- ./compiler/lua54.can:525 -["Break"] = function() -- ./compiler/lua54.can:528 -return "break" -- ./compiler/lua54.can:529 -end, -- ./compiler/lua54.can:529 -["Continue"] = function() -- ./compiler/lua54.can:532 -return "goto " .. var("continue") -- ./compiler/lua54.can:533 -end, -- ./compiler/lua54.can:533 -["Nil"] = function() -- ./compiler/lua54.can:540 -return "nil" -- ./compiler/lua54.can:541 -end, -- ./compiler/lua54.can:541 -["Dots"] = function() -- ./compiler/lua54.can:544 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 -return r -- ./compiler/lua54.can:550 -else -- ./compiler/lua54.can:550 -return "..." -- ./compiler/lua54.can:552 -end -- ./compiler/lua54.can:552 -end, -- ./compiler/lua54.can:552 -["Boolean"] = function(t) -- ./compiler/lua54.can:556 -return tostring(t[1]) -- ./compiler/lua54.can:557 -end, -- ./compiler/lua54.can:557 -["Number"] = function(t) -- ./compiler/lua54.can:560 -return tostring(t[1]) -- ./compiler/lua54.can:561 -end, -- ./compiler/lua54.can:561 -["String"] = function(t) -- ./compiler/lua54.can:564 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 -end, -- ./compiler/lua54.can:565 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 -local r = "(" -- ./compiler/lua54.can:569 -local decl = {} -- ./compiler/lua54.can:570 -if t[1][1] then -- ./compiler/lua54.can:571 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 -r = r .. (id) -- ./compiler/lua54.can:577 -else -- ./compiler/lua54.can:577 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 -end -- ./compiler/lua54.can:579 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 -r = r .. (", " .. id) -- ./compiler/lua54.can:587 -else -- ./compiler/lua54.can:587 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 -r = r .. (d .. newline()) -- ./compiler/lua54.can:595 -end -- ./compiler/lua54.can:595 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 -end -- ./compiler/lua54.can:598 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 -if hasPush then -- ./compiler/lua54.can:601 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 -else -- ./compiler/lua54.can:602 -push("push", false) -- ./compiler/lua54.can:604 -end -- ./compiler/lua54.can:604 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 -end -- ./compiler/lua54.can:608 -pop("push") -- ./compiler/lua54.can:610 -return r .. unindent() .. "end" -- ./compiler/lua54.can:611 -end, -- ./compiler/lua54.can:611 -["Function"] = function(t) -- ./compiler/lua54.can:613 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 -end, -- ./compiler/lua54.can:614 -["Pair"] = function(t) -- ./compiler/lua54.can:617 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 -end, -- ./compiler/lua54.can:618 -["Table"] = function(t) -- ./compiler/lua54.can:620 -if # t == 0 then -- ./compiler/lua54.can:621 -return "{}" -- ./compiler/lua54.can:622 -elseif # t == 1 then -- ./compiler/lua54.can:623 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 -else -- ./compiler/lua54.can:624 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 -end -- ./compiler/lua54.can:626 -end, -- ./compiler/lua54.can:626 -["TableCompr"] = function(t) -- ./compiler/lua54.can:630 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 -end, -- ./compiler/lua54.can:631 -["Op"] = function(t) -- ./compiler/lua54.can:634 -local r -- ./compiler/lua54.can:635 -if # t == 2 then -- ./compiler/lua54.can:636 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 -else -- ./compiler/lua54.can:638 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 -end -- ./compiler/lua54.can:640 +return r .. unindent() .. "end" -- ./compiler/lua54.can:448 +end -- ./compiler/lua54.can:448 +end, -- ./compiler/lua54.can:448 +["Forin"] = function(t) -- ./compiler/lua54.can:452 +local destructured = {} -- ./compiler/lua54.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 +if hasContinue then -- ./compiler/lua54.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 +end -- ./compiler/lua54.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 +if hasContinue then -- ./compiler/lua54.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 +end -- ./compiler/lua54.can:461 +return r .. unindent() .. "end" -- ./compiler/lua54.can:463 +end, -- ./compiler/lua54.can:463 +["Local"] = function(t) -- ./compiler/lua54.can:466 +local destructured = {} -- ./compiler/lua54.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 +if t[2][1] then -- ./compiler/lua54.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 +end -- ./compiler/lua54.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 +end, -- ./compiler/lua54.can:472 +["Let"] = function(t) -- ./compiler/lua54.can:475 +local destructured = {} -- ./compiler/lua54.can:476 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 +local r = "local " .. nameList -- ./compiler/lua54.can:478 +if t[2][1] then -- ./compiler/lua54.can:479 +if all(t[2], { -- ./compiler/lua54.can:480 +"Nil", -- ./compiler/lua54.can:480 +"Dots", -- ./compiler/lua54.can:480 +"Boolean", -- ./compiler/lua54.can:480 +"Number", -- ./compiler/lua54.can:480 +"String" -- ./compiler/lua54.can:480 +}) then -- ./compiler/lua54.can:480 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +else -- ./compiler/lua54.can:481 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Localrec"] = function(t) -- ./compiler/lua54.can:489 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Goto"] = function(t) -- ./compiler/lua54.can:493 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 +end, -- ./compiler/lua54.can:494 +["Label"] = function(t) -- ./compiler/lua54.can:497 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 +end, -- ./compiler/lua54.can:498 +["Return"] = function(t) -- ./compiler/lua54.can:501 +local push = peek("push") -- ./compiler/lua54.can:502 +if push then -- ./compiler/lua54.can:503 +local r = "" -- ./compiler/lua54.can:504 +for _, val in ipairs(t) do -- ./compiler/lua54.can:505 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 +end -- ./compiler/lua54.can:506 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 +else -- ./compiler/lua54.can:508 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +end, -- ./compiler/lua54.can:510 +["Push"] = function(t) -- ./compiler/lua54.can:514 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 +r = "" -- ./compiler/lua54.can:516 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 +end -- ./compiler/lua54.can:518 +if t[# t] then -- ./compiler/lua54.can:520 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 +else -- ./compiler/lua54.can:522 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +return r -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Break"] = function() -- ./compiler/lua54.can:530 +return "break" -- ./compiler/lua54.can:531 +end, -- ./compiler/lua54.can:531 +["Continue"] = function() -- ./compiler/lua54.can:534 +return "goto " .. var("continue") -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Nil"] = function() -- ./compiler/lua54.can:542 +return "nil" -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Dots"] = function() -- ./compiler/lua54.can:546 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 +return r -- ./compiler/lua54.can:552 +else -- ./compiler/lua54.can:552 +return "..." -- ./compiler/lua54.can:554 +end -- ./compiler/lua54.can:554 +end, -- ./compiler/lua54.can:554 +["Boolean"] = function(t) -- ./compiler/lua54.can:558 +return tostring(t[1]) -- ./compiler/lua54.can:559 +end, -- ./compiler/lua54.can:559 +["Number"] = function(t) -- ./compiler/lua54.can:562 +return tostring(t[1]) -- ./compiler/lua54.can:563 +end, -- ./compiler/lua54.can:563 +["String"] = function(t) -- ./compiler/lua54.can:566 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 +end, -- ./compiler/lua54.can:567 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 +local r = "(" -- ./compiler/lua54.can:571 +local decl = {} -- ./compiler/lua54.can:572 +if t[1][1] then -- ./compiler/lua54.can:573 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 +r = r .. (id) -- ./compiler/lua54.can:579 +else -- ./compiler/lua54.can:579 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 +r = r .. (", " .. id) -- ./compiler/lua54.can:589 +else -- ./compiler/lua54.can:589 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 +r = r .. (d .. newline()) -- ./compiler/lua54.can:597 +end -- ./compiler/lua54.can:597 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 +end -- ./compiler/lua54.can:600 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 +if hasPush then -- ./compiler/lua54.can:603 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 +else -- ./compiler/lua54.can:604 +push("push", false) -- ./compiler/lua54.can:606 +end -- ./compiler/lua54.can:606 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 +end -- ./compiler/lua54.can:610 +pop("push") -- ./compiler/lua54.can:612 +return r .. unindent() .. "end" -- ./compiler/lua54.can:613 +end, -- ./compiler/lua54.can:613 +["Function"] = function(t) -- ./compiler/lua54.can:615 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 +end, -- ./compiler/lua54.can:616 +["Pair"] = function(t) -- ./compiler/lua54.can:619 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 +end, -- ./compiler/lua54.can:620 +["Table"] = function(t) -- ./compiler/lua54.can:622 +if # t == 0 then -- ./compiler/lua54.can:623 +return "{}" -- ./compiler/lua54.can:624 +elseif # t == 1 then -- ./compiler/lua54.can:625 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 +end -- ./compiler/lua54.can:628 +end, -- ./compiler/lua54.can:628 +["TableCompr"] = function(t) -- ./compiler/lua54.can:632 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 +end, -- ./compiler/lua54.can:633 +["Op"] = function(t) -- ./compiler/lua54.can:636 +local r -- ./compiler/lua54.can:637 +if # t == 2 then -- ./compiler/lua54.can:638 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 else -- ./compiler/lua54.can:640 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 -else -- ./compiler/lua54.can:644 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -return r -- ./compiler/lua54.can:649 -end, -- ./compiler/lua54.can:649 -["Paren"] = function(t) -- ./compiler/lua54.can:652 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 -end, -- ./compiler/lua54.can:653 -["MethodStub"] = function(t) -- ./compiler/lua54.can:656 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 -end, -- ./compiler/lua54.can:662 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 -end, -- ./compiler/lua54.can:672 -["LetExpr"] = function(t) -- ./compiler/lua54.can:679 -return lua(t[1][1]) -- ./compiler/lua54.can:680 -end, -- ./compiler/lua54.can:680 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 -local r = "(function()" .. indent() -- ./compiler/lua54.can:686 -if hasPush then -- ./compiler/lua54.can:687 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 -else -- ./compiler/lua54.can:688 -push("push", false) -- ./compiler/lua54.can:690 -end -- ./compiler/lua54.can:690 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 -if hasPush then -- ./compiler/lua54.can:693 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 -end -- ./compiler/lua54.can:694 -pop("push") -- ./compiler/lua54.can:696 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 -return r -- ./compiler/lua54.can:698 -end, -- ./compiler/lua54.can:698 -["DoExpr"] = function(t) -- ./compiler/lua54.can:701 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 -end -- ./compiler/lua54.can:703 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 -end, -- ./compiler/lua54.can:705 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 -end, -- ./compiler/lua54.can:709 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 -end, -- ./compiler/lua54.can:713 -["IfExpr"] = function(t) -- ./compiler/lua54.can:716 -for i = 2, # t do -- ./compiler/lua54.can:717 -local block = t[i] -- ./compiler/lua54.can:718 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 -end, -- ./compiler/lua54.can:723 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 -end, -- ./compiler/lua54.can:727 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 -end, -- ./compiler/lua54.can:731 -["Call"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 -local replacement = macro["replacement"] -- ./compiler/lua54.can:742 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 -macroargs["..."] = (function() -- ./compiler/lua54.can:746 -local self = {} -- ./compiler/lua54.can:746 -for j = i + 1, # t do -- ./compiler/lua54.can:746 -self[#self+1] = t[j] -- ./compiler/lua54.can:746 -end -- ./compiler/lua54.can:746 -return self -- ./compiler/lua54.can:746 -end)() -- ./compiler/lua54.can:746 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 -if t[i + 1] == nil then -- ./compiler/lua54.can:748 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 -end -- ./compiler/lua54.can:749 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 -else -- ./compiler/lua54.can:751 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -push("macroargs", macroargs) -- ./compiler/lua54.can:756 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 -local r = lua(replacement) -- ./compiler/lua54.can:758 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 -pop("macroargs") -- ./compiler/lua54.can:760 -return r -- ./compiler/lua54.can:761 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 -else -- ./compiler/lua54.can:764 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 -end -- ./compiler/lua54.can:766 -else -- ./compiler/lua54.can:766 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 +end -- ./compiler/lua54.can:642 +else -- ./compiler/lua54.can:642 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 +else -- ./compiler/lua54.can:646 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +return r -- ./compiler/lua54.can:651 +end, -- ./compiler/lua54.can:651 +["Paren"] = function(t) -- ./compiler/lua54.can:654 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 +end, -- ./compiler/lua54.can:655 +["MethodStub"] = function(t) -- ./compiler/lua54.can:658 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 +end, -- ./compiler/lua54.can:664 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 +end, -- ./compiler/lua54.can:674 +["LetExpr"] = function(t) -- ./compiler/lua54.can:681 +return lua(t[1][1]) -- ./compiler/lua54.can:682 +end, -- ./compiler/lua54.can:682 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 +local r = "(function()" .. indent() -- ./compiler/lua54.can:688 +if hasPush then -- ./compiler/lua54.can:689 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 +else -- ./compiler/lua54.can:690 +push("push", false) -- ./compiler/lua54.can:692 +end -- ./compiler/lua54.can:692 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 +if hasPush then -- ./compiler/lua54.can:695 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 +end -- ./compiler/lua54.can:696 +pop("push") -- ./compiler/lua54.can:698 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 +return r -- ./compiler/lua54.can:700 +end, -- ./compiler/lua54.can:700 +["DoExpr"] = function(t) -- ./compiler/lua54.can:703 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 +end -- ./compiler/lua54.can:705 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 +end, -- ./compiler/lua54.can:707 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 +end, -- ./compiler/lua54.can:711 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 +end, -- ./compiler/lua54.can:715 +["IfExpr"] = function(t) -- ./compiler/lua54.can:718 +for i = 2, # t do -- ./compiler/lua54.can:719 +local block = t[i] -- ./compiler/lua54.can:720 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 +end, -- ./compiler/lua54.can:725 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 +end, -- ./compiler/lua54.can:729 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["Call"] = function(t) -- ./compiler/lua54.can:739 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 +local replacement = macro["replacement"] -- ./compiler/lua54.can:744 +local r -- ./compiler/lua54.can:745 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 +if type(replacement) == "function" then -- ./compiler/lua54.can:747 +local args = {} -- ./compiler/lua54.can:748 +for i = 2, # t do -- ./compiler/lua54.can:749 +table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 +end -- ./compiler/lua54.can:750 +r = replacement(unpack(args)) -- ./compiler/lua54.can:752 +else -- ./compiler/lua54.can:752 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 +macroargs["..."] = (function() -- ./compiler/lua54.can:757 +local self = {} -- ./compiler/lua54.can:757 +for j = i + 1, # t do -- ./compiler/lua54.can:757 +self[#self+1] = t[j] -- ./compiler/lua54.can:757 +end -- ./compiler/lua54.can:757 +return self -- ./compiler/lua54.can:757 +end)() -- ./compiler/lua54.can:757 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 +if t[i + 1] == nil then -- ./compiler/lua54.can:759 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 +end -- ./compiler/lua54.can:760 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 +else -- ./compiler/lua54.can:762 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +push("macroargs", macroargs) -- ./compiler/lua54.can:767 +r = lua(replacement) -- ./compiler/lua54.can:768 +pop("macroargs") -- ./compiler/lua54.can:769 end -- ./compiler/lua54.can:769 -end, -- ./compiler/lua54.can:769 -["SafeCall"] = function(t) -- ./compiler/lua54.can:773 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 +return r -- ./compiler/lua54.can:772 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 else -- ./compiler/lua54.can:775 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 end -- ./compiler/lua54.can:777 -end, -- ./compiler/lua54.can:777 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 -if start == nil then start = 1 end -- ./compiler/lua54.can:782 -local r -- ./compiler/lua54.can:783 -if t[start] then -- ./compiler/lua54.can:784 -r = lua(t[start]) -- ./compiler/lua54.can:785 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 -end -- ./compiler/lua54.can:787 -else -- ./compiler/lua54.can:787 -r = "" -- ./compiler/lua54.can:790 -end -- ./compiler/lua54.can:790 -return r -- ./compiler/lua54.can:792 -end, -- ./compiler/lua54.can:792 -["Id"] = function(t) -- ./compiler/lua54.can:795 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 -local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:802 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 -local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 -return r -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -return t[1] -- ./compiler/lua54.can:810 -end, -- ./compiler/lua54.can:810 -["AttributeId"] = function(t) -- ./compiler/lua54.can:813 -if t[2] then -- ./compiler/lua54.can:814 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 -else -- ./compiler/lua54.can:815 -return t[1] -- ./compiler/lua54.can:817 -end -- ./compiler/lua54.can:817 -end, -- ./compiler/lua54.can:817 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 -if t["id"] then -- ./compiler/lua54.can:822 -return t["id"] -- ./compiler/lua54.can:823 -else -- ./compiler/lua54.can:823 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 -for j = 1, # t, 1 do -- ./compiler/lua54.can:827 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 -end -- ./compiler/lua54.can:828 -table["insert"](d, vars) -- ./compiler/lua54.can:830 -t["id"] = vars["id"] -- ./compiler/lua54.can:831 -return vars["id"] -- ./compiler/lua54.can:832 -end -- ./compiler/lua54.can:832 -end, -- ./compiler/lua54.can:832 -["Index"] = function(t) -- ./compiler/lua54.can:836 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 -else -- ./compiler/lua54.can:838 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 -end -- ./compiler/lua54.can:840 -end, -- ./compiler/lua54.can:840 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 -local l = {} -- ./compiler/lua54.can:846 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 -table["insert"](l, 1, t) -- ./compiler/lua54.can:848 -t = t[1] -- ./compiler/lua54.can:849 -end -- ./compiler/lua54.can:849 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 -for _, e in ipairs(l) do -- ./compiler/lua54.can:852 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 -else -- ./compiler/lua54.can:855 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 -return r -- ./compiler/lua54.can:861 -else -- ./compiler/lua54.can:861 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 -end -- ./compiler/lua54.can:863 -end, -- ./compiler/lua54.can:863 -["_opid"] = { -- ./compiler/lua54.can:868 -["add"] = "+", -- ./compiler/lua54.can:869 -["sub"] = "-", -- ./compiler/lua54.can:869 -["mul"] = "*", -- ./compiler/lua54.can:869 -["div"] = "/", -- ./compiler/lua54.can:869 -["idiv"] = "//", -- ./compiler/lua54.can:870 -["mod"] = "%", -- ./compiler/lua54.can:870 -["pow"] = "^", -- ./compiler/lua54.can:870 -["concat"] = "..", -- ./compiler/lua54.can:870 -["band"] = "&", -- ./compiler/lua54.can:871 -["bor"] = "|", -- ./compiler/lua54.can:871 -["bxor"] = "~", -- ./compiler/lua54.can:871 -["shl"] = "<<", -- ./compiler/lua54.can:871 -["shr"] = ">>", -- ./compiler/lua54.can:871 -["eq"] = "==", -- ./compiler/lua54.can:872 -["ne"] = "~=", -- ./compiler/lua54.can:872 -["lt"] = "<", -- ./compiler/lua54.can:872 -["gt"] = ">", -- ./compiler/lua54.can:872 -["le"] = "<=", -- ./compiler/lua54.can:872 -["ge"] = ">=", -- ./compiler/lua54.can:872 -["and"] = "and", -- ./compiler/lua54.can:873 -["or"] = "or", -- ./compiler/lua54.can:873 -["unm"] = "-", -- ./compiler/lua54.can:873 -["len"] = "#", -- ./compiler/lua54.can:873 -["bnot"] = "~", -- ./compiler/lua54.can:873 -["not"] = "not" -- ./compiler/lua54.can:873 -} -- ./compiler/lua54.can:873 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 -end }) -- ./compiler/lua54.can:877 +else -- ./compiler/lua54.can:777 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 +end -- ./compiler/lua54.can:780 +end, -- ./compiler/lua54.can:780 +["SafeCall"] = function(t) -- ./compiler/lua54.can:784 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 +else -- ./compiler/lua54.can:786 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 +end -- ./compiler/lua54.can:788 +end, -- ./compiler/lua54.can:788 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 +if start == nil then start = 1 end -- ./compiler/lua54.can:793 +local r -- ./compiler/lua54.can:794 +if t[start] then -- ./compiler/lua54.can:795 +r = lua(t[start]) -- ./compiler/lua54.can:796 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 +end -- ./compiler/lua54.can:798 +else -- ./compiler/lua54.can:798 +r = "" -- ./compiler/lua54.can:801 +end -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:803 +end, -- ./compiler/lua54.can:803 +["Id"] = function(t) -- ./compiler/lua54.can:806 +local r = t[1] -- ./compiler/lua54.can:807 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 +r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 +local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 +if type(macro) == "function" then -- ./compiler/lua54.can:815 +r = macro() -- ./compiler/lua54.can:816 +else -- ./compiler/lua54.can:816 +r = lua(macro) -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 +end -- ./compiler/lua54.can:821 +return r -- ./compiler/lua54.can:823 +end, -- ./compiler/lua54.can:823 +["AttributeId"] = function(t) -- ./compiler/lua54.can:826 +if t[2] then -- ./compiler/lua54.can:827 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 +else -- ./compiler/lua54.can:828 +return t[1] -- ./compiler/lua54.can:830 +end -- ./compiler/lua54.can:830 +end, -- ./compiler/lua54.can:830 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 +if t["id"] then -- ./compiler/lua54.can:835 +return t["id"] -- ./compiler/lua54.can:836 +else -- ./compiler/lua54.can:836 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 +for j = 1, # t, 1 do -- ./compiler/lua54.can:840 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 +end -- ./compiler/lua54.can:841 +table["insert"](d, vars) -- ./compiler/lua54.can:843 +t["id"] = vars["id"] -- ./compiler/lua54.can:844 +return vars["id"] -- ./compiler/lua54.can:845 +end -- ./compiler/lua54.can:845 +end, -- ./compiler/lua54.can:845 +["Index"] = function(t) -- ./compiler/lua54.can:849 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 +else -- ./compiler/lua54.can:851 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 +end -- ./compiler/lua54.can:853 +end, -- ./compiler/lua54.can:853 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 +local l = {} -- ./compiler/lua54.can:859 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 +table["insert"](l, 1, t) -- ./compiler/lua54.can:861 +t = t[1] -- ./compiler/lua54.can:862 +end -- ./compiler/lua54.can:862 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 +for _, e in ipairs(l) do -- ./compiler/lua54.can:865 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 +else -- ./compiler/lua54.can:868 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 +return r -- ./compiler/lua54.can:874 +else -- ./compiler/lua54.can:874 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 +end -- ./compiler/lua54.can:876 +end, -- ./compiler/lua54.can:876 +["_opid"] = { -- ./compiler/lua54.can:881 +["add"] = "+", -- ./compiler/lua54.can:882 +["sub"] = "-", -- ./compiler/lua54.can:882 +["mul"] = "*", -- ./compiler/lua54.can:882 +["div"] = "/", -- ./compiler/lua54.can:882 +["idiv"] = "//", -- ./compiler/lua54.can:883 +["mod"] = "%", -- ./compiler/lua54.can:883 +["pow"] = "^", -- ./compiler/lua54.can:883 +["concat"] = "..", -- ./compiler/lua54.can:883 +["band"] = "&", -- ./compiler/lua54.can:884 +["bor"] = "|", -- ./compiler/lua54.can:884 +["bxor"] = "~", -- ./compiler/lua54.can:884 +["shl"] = "<<", -- ./compiler/lua54.can:884 +["shr"] = ">>", -- ./compiler/lua54.can:884 +["eq"] = "==", -- ./compiler/lua54.can:885 +["ne"] = "~=", -- ./compiler/lua54.can:885 +["lt"] = "<", -- ./compiler/lua54.can:885 +["gt"] = ">", -- ./compiler/lua54.can:885 +["le"] = "<=", -- ./compiler/lua54.can:885 +["ge"] = ">=", -- ./compiler/lua54.can:885 +["and"] = "and", -- ./compiler/lua54.can:886 +["or"] = "or", -- ./compiler/lua54.can:886 +["unm"] = "-", -- ./compiler/lua54.can:886 +["len"] = "#", -- ./compiler/lua54.can:886 +["bnot"] = "~", -- ./compiler/lua54.can:886 +["not"] = "not" -- ./compiler/lua54.can:886 +} -- ./compiler/lua54.can:886 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 +end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -1988,11 +2012,11 @@ else -- ./compiler/lua53.can:6 return t[1] -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 end -- ./compiler/lua53.can:8 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 -return requireStr .. code -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -local lua54 = _() or lua54 -- ./compiler/lua54.can:889 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 +return requireStr .. code -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +local lua54 = _() or lua54 -- ./compiler/lua54.can:902 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -2002,919 +2026,931 @@ local function _() -- ./compiler/lua53.can:28 local function _() -- ./compiler/lua53.can:30 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -return function(code, ast, options, macros) -- ./compiler/lua54.can:5 -if macros == nil then macros = { -- ./compiler/lua54.can:5 -["functions"] = {}, -- ./compiler/lua54.can:5 -["variables"] = {} -- ./compiler/lua54.can:5 -} end -- ./compiler/lua54.can:5 -local lastInputPos = 1 -- ./compiler/lua54.can:7 -local prevLinePos = 1 -- ./compiler/lua54.can:8 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 -local lastLine = 1 -- ./compiler/lua54.can:10 -local indentLevel = 0 -- ./compiler/lua54.can:13 -local function newline() -- ./compiler/lua54.can:15 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 -if options["mapLines"] then -- ./compiler/lua54.can:17 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 +local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 +return function(code, ast, options, macros) -- ./compiler/lua54.can:7 +if macros == nil then macros = { -- ./compiler/lua54.can:7 +["functions"] = {}, -- ./compiler/lua54.can:7 +["variables"] = {} -- ./compiler/lua54.can:7 +} end -- ./compiler/lua54.can:7 +local lastInputPos = 1 -- ./compiler/lua54.can:9 +local prevLinePos = 1 -- ./compiler/lua54.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 +local lastLine = 1 -- ./compiler/lua54.can:12 +local indentLevel = 0 -- ./compiler/lua54.can:15 +local function newline() -- ./compiler/lua54.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 +if options["mapLines"] then -- ./compiler/lua54.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:19 -if source and line then -- ./compiler/lua54.can:21 -lastSource = source -- ./compiler/lua54.can:22 -lastLine = tonumber(line) -- ./compiler/lua54.can:23 -else -- ./compiler/lua54.can:23 +") -- ./compiler/lua54.can:21 +if source and line then -- ./compiler/lua54.can:23 +lastSource = source -- ./compiler/lua54.can:24 +lastLine = tonumber(line) -- ./compiler/lua54.can:25 +else -- ./compiler/lua54.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:25 -lastLine = lastLine + (1) -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -prevLinePos = lastInputPos -- ./compiler/lua54.can:30 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 -end -- ./compiler/lua54.can:32 -return r -- ./compiler/lua54.can:34 +") do -- ./compiler/lua54.can:27 +lastLine = lastLine + (1) -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +prevLinePos = lastInputPos -- ./compiler/lua54.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 end -- ./compiler/lua54.can:34 -local function indent() -- ./compiler/lua54.can:37 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 -return newline() -- ./compiler/lua54.can:39 -end -- ./compiler/lua54.can:39 -local function unindent() -- ./compiler/lua54.can:42 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 -return newline() -- ./compiler/lua54.can:44 -end -- ./compiler/lua54.can:44 -local states = { -- ./compiler/lua54.can:49 -["push"] = {}, -- ./compiler/lua54.can:50 -["destructuring"] = {}, -- ./compiler/lua54.can:51 -["scope"] = {}, -- ./compiler/lua54.can:52 -["macroargs"] = {} -- ./compiler/lua54.can:53 -} -- ./compiler/lua54.can:53 -local function push(name, state) -- ./compiler/lua54.can:56 -table["insert"](states[name], state) -- ./compiler/lua54.can:57 -return "" -- ./compiler/lua54.can:58 -end -- ./compiler/lua54.can:58 -local function pop(name) -- ./compiler/lua54.can:61 -table["remove"](states[name]) -- ./compiler/lua54.can:62 -return "" -- ./compiler/lua54.can:63 -end -- ./compiler/lua54.can:63 -local function set(name, state) -- ./compiler/lua54.can:66 -states[name][# states[name]] = state -- ./compiler/lua54.can:67 -return "" -- ./compiler/lua54.can:68 -end -- ./compiler/lua54.can:68 -local function peek(name) -- ./compiler/lua54.can:71 -return states[name][# states[name]] -- ./compiler/lua54.can:72 -end -- ./compiler/lua54.can:72 -local function var(name) -- ./compiler/lua54.can:77 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 -end -- ./compiler/lua54.can:78 -local function tmp() -- ./compiler/lua54.can:82 -local scope = peek("scope") -- ./compiler/lua54.can:83 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 -table["insert"](scope, var) -- ./compiler/lua54.can:85 -return var -- ./compiler/lua54.can:86 -end -- ./compiler/lua54.can:86 -local nomacro = { -- ./compiler/lua54.can:90 -["variables"] = {}, -- ./compiler/lua54.can:90 -["functions"] = {} -- ./compiler/lua54.can:90 -} -- ./compiler/lua54.can:90 -local required = {} -- ./compiler/lua54.can:93 -local requireStr = "" -- ./compiler/lua54.can:94 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 -if not required[req] then -- ./compiler/lua54.can:98 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 -required[req] = true -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -local loop = { -- ./compiler/lua54.can:105 -"While", -- ./compiler/lua54.can:105 -"Repeat", -- ./compiler/lua54.can:105 -"Fornum", -- ./compiler/lua54.can:105 -"Forin", -- ./compiler/lua54.can:105 -"WhileExpr", -- ./compiler/lua54.can:105 -"RepeatExpr", -- ./compiler/lua54.can:105 -"FornumExpr", -- ./compiler/lua54.can:105 -"ForinExpr" -- ./compiler/lua54.can:105 -} -- ./compiler/lua54.can:105 -local func = { -- ./compiler/lua54.can:106 -"Function", -- ./compiler/lua54.can:106 -"TableCompr", -- ./compiler/lua54.can:106 -"DoExpr", -- ./compiler/lua54.can:106 -"WhileExpr", -- ./compiler/lua54.can:106 -"RepeatExpr", -- ./compiler/lua54.can:106 -"IfExpr", -- ./compiler/lua54.can:106 -"FornumExpr", -- ./compiler/lua54.can:106 -"ForinExpr" -- ./compiler/lua54.can:106 -} -- ./compiler/lua54.can:106 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 -local tagsCheck = {} -- ./compiler/lua54.can:111 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 -tagsCheck[tag] = true -- ./compiler/lua54.can:113 -end -- ./compiler/lua54.can:113 -local nofollowCheck = {} -- ./compiler/lua54.can:115 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 -nofollowCheck[tag] = true -- ./compiler/lua54.can:117 -end -- ./compiler/lua54.can:117 -for _, node in ipairs(list) do -- ./compiler/lua54.can:119 -if type(node) == "table" then -- ./compiler/lua54.can:120 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 -return node -- ./compiler/lua54.can:122 -end -- ./compiler/lua54.can:122 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 -if r then -- ./compiler/lua54.can:126 -return r -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -return nil -- ./compiler/lua54.can:130 -end -- ./compiler/lua54.can:130 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 -local tagsCheck = {} -- ./compiler/lua54.can:136 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 -tagsCheck[tag] = true -- ./compiler/lua54.can:138 -end -- ./compiler/lua54.can:138 -local nofollowCheck = {} -- ./compiler/lua54.can:140 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 -nofollowCheck[tag] = true -- ./compiler/lua54.can:142 -end -- ./compiler/lua54.can:142 -local found = {} -- ./compiler/lua54.can:144 -for _, node in ipairs(list) do -- ./compiler/lua54.can:145 -if type(node) == "table" then -- ./compiler/lua54.can:146 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 -table["insert"](found, n) -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 -table["insert"](found, node) -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -return found -- ./compiler/lua54.can:157 -end -- ./compiler/lua54.can:157 -local function all(list, tags) -- ./compiler/lua54.can:161 -for _, node in ipairs(list) do -- ./compiler/lua54.can:162 -local ok = false -- ./compiler/lua54.can:163 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 -if node["tag"] == tag then -- ./compiler/lua54.can:165 -ok = true -- ./compiler/lua54.can:166 -break -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -if not ok then -- ./compiler/lua54.can:170 -return false -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -return true -- ./compiler/lua54.can:174 -end -- ./compiler/lua54.can:174 -local tags -- ./compiler/lua54.can:178 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 -end -- ./compiler/lua54.can:182 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +return r -- ./compiler/lua54.can:36 +end -- ./compiler/lua54.can:36 +local function indent() -- ./compiler/lua54.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 +return newline() -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local function unindent() -- ./compiler/lua54.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 +return newline() -- ./compiler/lua54.can:46 +end -- ./compiler/lua54.can:46 +local states = { -- ./compiler/lua54.can:51 +["push"] = {}, -- ./compiler/lua54.can:52 +["destructuring"] = {}, -- ./compiler/lua54.can:53 +["scope"] = {}, -- ./compiler/lua54.can:54 +["macroargs"] = {} -- ./compiler/lua54.can:55 +} -- ./compiler/lua54.can:55 +local function push(name, state) -- ./compiler/lua54.can:58 +table["insert"](states[name], state) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function pop(name) -- ./compiler/lua54.can:63 +table["remove"](states[name]) -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function set(name, state) -- ./compiler/lua54.can:68 +states[name][# states[name]] = state -- ./compiler/lua54.can:69 +return "" -- ./compiler/lua54.can:70 +end -- ./compiler/lua54.can:70 +local function peek(name) -- ./compiler/lua54.can:73 +return states[name][# states[name]] -- ./compiler/lua54.can:74 +end -- ./compiler/lua54.can:74 +local function var(name) -- ./compiler/lua54.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 +end -- ./compiler/lua54.can:80 +local function tmp() -- ./compiler/lua54.can:84 +local scope = peek("scope") -- ./compiler/lua54.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 +table["insert"](scope, var) -- ./compiler/lua54.can:87 +return var -- ./compiler/lua54.can:88 +end -- ./compiler/lua54.can:88 +local nomacro = { -- ./compiler/lua54.can:92 +["variables"] = {}, -- ./compiler/lua54.can:92 +["functions"] = {} -- ./compiler/lua54.can:92 +} -- ./compiler/lua54.can:92 +local required = {} -- ./compiler/lua54.can:95 +local requireStr = "" -- ./compiler/lua54.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 +if not required[req] then -- ./compiler/lua54.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 +required[req] = true -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +local loop = { -- ./compiler/lua54.can:107 +"While", -- ./compiler/lua54.can:107 +"Repeat", -- ./compiler/lua54.can:107 +"Fornum", -- ./compiler/lua54.can:107 +"Forin", -- ./compiler/lua54.can:107 +"WhileExpr", -- ./compiler/lua54.can:107 +"RepeatExpr", -- ./compiler/lua54.can:107 +"FornumExpr", -- ./compiler/lua54.can:107 +"ForinExpr" -- ./compiler/lua54.can:107 +} -- ./compiler/lua54.can:107 +local func = { -- ./compiler/lua54.can:108 +"Function", -- ./compiler/lua54.can:108 +"TableCompr", -- ./compiler/lua54.can:108 +"DoExpr", -- ./compiler/lua54.can:108 +"WhileExpr", -- ./compiler/lua54.can:108 +"RepeatExpr", -- ./compiler/lua54.can:108 +"IfExpr", -- ./compiler/lua54.can:108 +"FornumExpr", -- ./compiler/lua54.can:108 +"ForinExpr" -- ./compiler/lua54.can:108 +} -- ./compiler/lua54.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 +local tagsCheck = {} -- ./compiler/lua54.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 +tagsCheck[tag] = true -- ./compiler/lua54.can:115 +end -- ./compiler/lua54.can:115 +local nofollowCheck = {} -- ./compiler/lua54.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 +nofollowCheck[tag] = true -- ./compiler/lua54.can:119 +end -- ./compiler/lua54.can:119 +for _, node in ipairs(list) do -- ./compiler/lua54.can:121 +if type(node) == "table" then -- ./compiler/lua54.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 +return node -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 +if r then -- ./compiler/lua54.can:128 +return r -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +return nil -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 +local tagsCheck = {} -- ./compiler/lua54.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 +tagsCheck[tag] = true -- ./compiler/lua54.can:140 +end -- ./compiler/lua54.can:140 +local nofollowCheck = {} -- ./compiler/lua54.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 +nofollowCheck[tag] = true -- ./compiler/lua54.can:144 +end -- ./compiler/lua54.can:144 +local found = {} -- ./compiler/lua54.can:146 +for _, node in ipairs(list) do -- ./compiler/lua54.can:147 +if type(node) == "table" then -- ./compiler/lua54.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 +table["insert"](found, n) -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 +table["insert"](found, node) -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +return found -- ./compiler/lua54.can:159 +end -- ./compiler/lua54.can:159 +local function all(list, tags) -- ./compiler/lua54.can:163 +for _, node in ipairs(list) do -- ./compiler/lua54.can:164 +local ok = false -- ./compiler/lua54.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 +if node["tag"] == tag then -- ./compiler/lua54.can:167 +ok = true -- ./compiler/lua54.can:168 +break -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +if not ok then -- ./compiler/lua54.can:172 +return false -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +return true -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +local tags -- ./compiler/lua54.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 end -- ./compiler/lua54.can:184 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 -end -- ./compiler/lua54.can:189 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 -end -- ./compiler/lua54.can:192 -local CONTINUE_START = function() -- ./compiler/lua54.can:194 -return "do" .. indent() -- ./compiler/lua54.can:195 -end -- ./compiler/lua54.can:195 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 -end -- ./compiler/lua54.can:198 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 -local vars = {} -- ./compiler/lua54.can:201 -local values = {} -- ./compiler/lua54.can:202 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 -for _, v in ipairs(list) do -- ./compiler/lua54.can:204 -local var, val -- ./compiler/lua54.can:205 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 -var = v -- ./compiler/lua54.can:207 -val = { -- ./compiler/lua54.can:208 -["tag"] = "Index", -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "Id", -- ./compiler/lua54.can:208 -list["id"] -- ./compiler/lua54.can:208 -}, -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "String", -- ./compiler/lua54.can:208 -v[1] -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 -var = v[2] -- ./compiler/lua54.can:210 -val = { -- ./compiler/lua54.can:211 -["tag"] = "Index", -- ./compiler/lua54.can:211 -{ -- ./compiler/lua54.can:211 -["tag"] = "Id", -- ./compiler/lua54.can:211 -list["id"] -- ./compiler/lua54.can:211 -}, -- ./compiler/lua54.can:211 -v[1] -- ./compiler/lua54.can:211 -} -- ./compiler/lua54.can:211 -else -- ./compiler/lua54.can:211 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 -end -- ./compiler/lua54.can:213 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 -val = { -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["rightOp"], -- ./compiler/lua54.can:216 -var, -- ./compiler/lua54.can:216 -{ -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["leftOp"], -- ./compiler/lua54.can:216 -val, -- ./compiler/lua54.can:216 -var -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 +end -- ./compiler/lua54.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 +end -- ./compiler/lua54.can:194 +local CONTINUE_START = function() -- ./compiler/lua54.can:196 +return "do" .. indent() -- ./compiler/lua54.can:197 +end -- ./compiler/lua54.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 +end -- ./compiler/lua54.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 +local vars = {} -- ./compiler/lua54.can:203 +local values = {} -- ./compiler/lua54.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 +for _, v in ipairs(list) do -- ./compiler/lua54.can:206 +local var, val -- ./compiler/lua54.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 +var = v -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Index", -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Id", -- ./compiler/lua54.can:210 +list["id"] -- ./compiler/lua54.can:210 +}, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "String", -- ./compiler/lua54.can:210 +v[1] -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 +var = v[2] -- ./compiler/lua54.can:212 +val = { -- ./compiler/lua54.can:213 +["tag"] = "Index", -- ./compiler/lua54.can:213 +{ -- ./compiler/lua54.can:213 +["tag"] = "Id", -- ./compiler/lua54.can:213 +list["id"] -- ./compiler/lua54.can:213 +}, -- ./compiler/lua54.can:213 +v[1] -- ./compiler/lua54.can:213 +} -- ./compiler/lua54.can:213 +else -- ./compiler/lua54.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 +end -- ./compiler/lua54.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 val = { -- ./compiler/lua54.can:218 ["tag"] = "Op", -- ./compiler/lua54.can:218 destructured["rightOp"], -- ./compiler/lua54.can:218 var, -- ./compiler/lua54.can:218 -val -- ./compiler/lua54.can:218 +{ -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["leftOp"], -- ./compiler/lua54.can:218 +val, -- ./compiler/lua54.can:218 +var -- ./compiler/lua54.can:218 } -- ./compiler/lua54.can:218 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +} -- ./compiler/lua54.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 val = { -- ./compiler/lua54.can:220 ["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["leftOp"], -- ./compiler/lua54.can:220 -val, -- ./compiler/lua54.can:220 -var -- ./compiler/lua54.can:220 +destructured["rightOp"], -- ./compiler/lua54.can:220 +var, -- ./compiler/lua54.can:220 +val -- ./compiler/lua54.can:220 } -- ./compiler/lua54.can:220 -end -- ./compiler/lua54.can:220 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -if # vars > 0 then -- ./compiler/lua54.can:226 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 -if newlineAfter then -- ./compiler/lua54.can:228 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 -else -- ./compiler/lua54.can:229 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 -end -- ./compiler/lua54.can:231 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 +val = { -- ./compiler/lua54.can:222 +["tag"] = "Op", -- ./compiler/lua54.can:222 +destructured["leftOp"], -- ./compiler/lua54.can:222 +val, -- ./compiler/lua54.can:222 +var -- ./compiler/lua54.can:222 +} -- ./compiler/lua54.can:222 +end -- ./compiler/lua54.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +if # vars > 0 then -- ./compiler/lua54.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 +if newlineAfter then -- ./compiler/lua54.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 else -- ./compiler/lua54.can:231 -return "" -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -tags = setmetatable({ -- ./compiler/lua54.can:239 -["Block"] = function(t) -- ./compiler/lua54.can:241 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 -hasPush = false -- ./compiler/lua54.can:245 -end -- ./compiler/lua54.can:245 -local r = push("scope", {}) -- ./compiler/lua54.can:247 -if hasPush then -- ./compiler/lua54.can:248 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 -end -- ./compiler/lua54.can:249 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 -end -- ./compiler/lua54.can:252 -if t[# t] then -- ./compiler/lua54.can:254 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 -end -- ./compiler/lua54.can:255 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 -end -- ./compiler/lua54.can:258 -return r .. pop("scope") -- ./compiler/lua54.can:260 -end, -- ./compiler/lua54.can:260 -["Do"] = function(t) -- ./compiler/lua54.can:266 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 -end, -- ./compiler/lua54.can:267 -["Set"] = function(t) -- ./compiler/lua54.can:270 -local expr = t[# t] -- ./compiler/lua54.can:272 -local vars, values = {}, {} -- ./compiler/lua54.can:273 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 -else -- ./compiler/lua54.can:278 -table["insert"](vars, n) -- ./compiler/lua54.can:280 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 -local r = "" -- ./compiler/lua54.can:286 -if # vars > 0 then -- ./compiler/lua54.can:287 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 -end -- ./compiler/lua54.can:288 -if # destructuringVars > 0 then -- ./compiler/lua54.can:290 -local destructured = {} -- ./compiler/lua54.can:291 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 -end -- ./compiler/lua54.can:293 -return r -- ./compiler/lua54.can:295 -elseif # t == 4 then -- ./compiler/lua54.can:296 -if t[3] == "=" then -- ./compiler/lua54.can:297 -local r = "" -- ./compiler/lua54.can:298 -if # vars > 0 then -- ./compiler/lua54.can:299 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 -t[2], -- ./compiler/lua54.can:300 -vars[1], -- ./compiler/lua54.can:300 -{ -- ./compiler/lua54.can:300 -["tag"] = "Paren", -- ./compiler/lua54.can:300 -values[1] -- ./compiler/lua54.can:300 -} -- ./compiler/lua54.can:300 -}, "Op")) -- ./compiler/lua54.can:300 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 +end -- ./compiler/lua54.can:233 +else -- ./compiler/lua54.can:233 +return "" -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +tags = setmetatable({ -- ./compiler/lua54.can:241 +["Block"] = function(t) -- ./compiler/lua54.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 +hasPush = false -- ./compiler/lua54.can:247 +end -- ./compiler/lua54.can:247 +local r = push("scope", {}) -- ./compiler/lua54.can:249 +if hasPush then -- ./compiler/lua54.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 +end -- ./compiler/lua54.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 +end -- ./compiler/lua54.can:254 +if t[# t] then -- ./compiler/lua54.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 +end -- ./compiler/lua54.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 +end -- ./compiler/lua54.can:260 +return r .. pop("scope") -- ./compiler/lua54.can:262 +end, -- ./compiler/lua54.can:262 +["Do"] = function(t) -- ./compiler/lua54.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 +end, -- ./compiler/lua54.can:269 +["Set"] = function(t) -- ./compiler/lua54.can:272 +local expr = t[# t] -- ./compiler/lua54.can:274 +local vars, values = {}, {} -- ./compiler/lua54.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 +else -- ./compiler/lua54.can:280 +table["insert"](vars, n) -- ./compiler/lua54.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 +local r = "" -- ./compiler/lua54.can:288 +if # vars > 0 then -- ./compiler/lua54.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 +end -- ./compiler/lua54.can:290 +if # destructuringVars > 0 then -- ./compiler/lua54.can:292 +local destructured = {} -- ./compiler/lua54.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 +end -- ./compiler/lua54.can:295 +return r -- ./compiler/lua54.can:297 +elseif # t == 4 then -- ./compiler/lua54.can:298 +if t[3] == "=" then -- ./compiler/lua54.can:299 +local r = "" -- ./compiler/lua54.can:300 +if # vars > 0 then -- ./compiler/lua54.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 t[2], -- ./compiler/lua54.can:302 -vars[i], -- ./compiler/lua54.can:302 +vars[1], -- ./compiler/lua54.can:302 { -- ./compiler/lua54.can:302 ["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[i] -- ./compiler/lua54.can:302 +values[1] -- ./compiler/lua54.can:302 } -- ./compiler/lua54.can:302 }, "Op")) -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -if # destructuringVars > 0 then -- ./compiler/lua54.can:305 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 -end -- ./compiler/lua54.can:308 -return r -- ./compiler/lua54.can:310 -else -- ./compiler/lua54.can:310 -local r = "" -- ./compiler/lua54.can:312 -if # vars > 0 then -- ./compiler/lua54.can:313 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 -t[3], -- ./compiler/lua54.can:314 -{ -- ./compiler/lua54.can:314 -["tag"] = "Paren", -- ./compiler/lua54.can:314 -values[1] -- ./compiler/lua54.can:314 -}, -- ./compiler/lua54.can:314 -vars[1] -- ./compiler/lua54.can:314 -}, "Op")) -- ./compiler/lua54.can:314 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 +t[2], -- ./compiler/lua54.can:304 +vars[i], -- ./compiler/lua54.can:304 +{ -- ./compiler/lua54.can:304 +["tag"] = "Paren", -- ./compiler/lua54.can:304 +values[i] -- ./compiler/lua54.can:304 +} -- ./compiler/lua54.can:304 +}, "Op")) -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +if # destructuringVars > 0 then -- ./compiler/lua54.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +return r -- ./compiler/lua54.can:312 +else -- ./compiler/lua54.can:312 +local r = "" -- ./compiler/lua54.can:314 +if # vars > 0 then -- ./compiler/lua54.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 t[3], -- ./compiler/lua54.can:316 { -- ./compiler/lua54.can:316 ["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[i] -- ./compiler/lua54.can:316 +values[1] -- ./compiler/lua54.can:316 }, -- ./compiler/lua54.can:316 -vars[i] -- ./compiler/lua54.can:316 +vars[1] -- ./compiler/lua54.can:316 }, "Op")) -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -if # destructuringVars > 0 then -- ./compiler/lua54.can:319 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 -end -- ./compiler/lua54.can:322 -return r -- ./compiler/lua54.can:324 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 +t[3], -- ./compiler/lua54.can:318 +{ -- ./compiler/lua54.can:318 +["tag"] = "Paren", -- ./compiler/lua54.can:318 +values[i] -- ./compiler/lua54.can:318 +}, -- ./compiler/lua54.can:318 +vars[i] -- ./compiler/lua54.can:318 +}, "Op")) -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +if # destructuringVars > 0 then -- ./compiler/lua54.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 end -- ./compiler/lua54.can:324 -else -- ./compiler/lua54.can:324 -local r = "" -- ./compiler/lua54.can:327 -if # vars > 0 then -- ./compiler/lua54.can:328 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 -t[2], -- ./compiler/lua54.can:329 -vars[1], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Op", -- ./compiler/lua54.can:329 -t[4], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Paren", -- ./compiler/lua54.can:329 -values[1] -- ./compiler/lua54.can:329 -}, -- ./compiler/lua54.can:329 -vars[1] -- ./compiler/lua54.can:329 -} -- ./compiler/lua54.can:329 -}, "Op")) -- ./compiler/lua54.can:329 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:326 +end -- ./compiler/lua54.can:326 +else -- ./compiler/lua54.can:326 +local r = "" -- ./compiler/lua54.can:329 +if # vars > 0 then -- ./compiler/lua54.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 t[2], -- ./compiler/lua54.can:331 -vars[i], -- ./compiler/lua54.can:331 +vars[1], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Op", -- ./compiler/lua54.can:331 t[4], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[i] -- ./compiler/lua54.can:331 +values[1] -- ./compiler/lua54.can:331 }, -- ./compiler/lua54.can:331 -vars[i] -- ./compiler/lua54.can:331 +vars[1] -- ./compiler/lua54.can:331 } -- ./compiler/lua54.can:331 }, "Op")) -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -if # destructuringVars > 0 then -- ./compiler/lua54.can:334 -local destructured = { -- ./compiler/lua54.can:335 -["rightOp"] = t[2], -- ./compiler/lua54.can:335 -["leftOp"] = t[4] -- ./compiler/lua54.can:335 -} -- ./compiler/lua54.can:335 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 -end -- ./compiler/lua54.can:337 -return r -- ./compiler/lua54.can:339 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 +t[2], -- ./compiler/lua54.can:333 +vars[i], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Op", -- ./compiler/lua54.can:333 +t[4], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Paren", -- ./compiler/lua54.can:333 +values[i] -- ./compiler/lua54.can:333 +}, -- ./compiler/lua54.can:333 +vars[i] -- ./compiler/lua54.can:333 +} -- ./compiler/lua54.can:333 +}, "Op")) -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +if # destructuringVars > 0 then -- ./compiler/lua54.can:336 +local destructured = { -- ./compiler/lua54.can:337 +["rightOp"] = t[2], -- ./compiler/lua54.can:337 +["leftOp"] = t[4] -- ./compiler/lua54.can:337 +} -- ./compiler/lua54.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 end -- ./compiler/lua54.can:339 -end, -- ./compiler/lua54.can:339 -["While"] = function(t) -- ./compiler/lua54.can:343 -local r = "" -- ./compiler/lua54.can:344 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 -if # lets > 0 then -- ./compiler/lua54.can:347 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 -if # lets > 0 then -- ./compiler/lua54.can:354 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 -end -- ./compiler/lua54.can:355 -if hasContinue then -- ./compiler/lua54.can:357 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 -end -- ./compiler/lua54.can:358 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 -if hasContinue then -- ./compiler/lua54.can:361 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 -end -- ./compiler/lua54.can:362 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 -if # lets > 0 then -- ./compiler/lua54.can:365 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 -end -- ./compiler/lua54.can:367 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:341 +end -- ./compiler/lua54.can:341 +end, -- ./compiler/lua54.can:341 +["While"] = function(t) -- ./compiler/lua54.can:345 +local r = "" -- ./compiler/lua54.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 +if # lets > 0 then -- ./compiler/lua54.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 +if # lets > 0 then -- ./compiler/lua54.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 +end -- ./compiler/lua54.can:357 +if hasContinue then -- ./compiler/lua54.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 +end -- ./compiler/lua54.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 +if hasContinue then -- ./compiler/lua54.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 +end -- ./compiler/lua54.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 +if # lets > 0 then -- ./compiler/lua54.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 end -- ./compiler/lua54.can:369 -return r -- ./compiler/lua54.can:371 -end, -- ./compiler/lua54.can:371 -["Repeat"] = function(t) -- ./compiler/lua54.can:374 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 -local r = "repeat" .. indent() -- ./compiler/lua54.can:376 -if hasContinue then -- ./compiler/lua54.can:377 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 -end -- ./compiler/lua54.can:378 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 -if hasContinue then -- ./compiler/lua54.can:381 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 -end -- ./compiler/lua54.can:382 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 -return r -- ./compiler/lua54.can:385 -end, -- ./compiler/lua54.can:385 -["If"] = function(t) -- ./compiler/lua54.can:388 -local r = "" -- ./compiler/lua54.can:389 -local toClose = 0 -- ./compiler/lua54.can:390 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 -if # lets > 0 then -- ./compiler/lua54.can:392 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 -toClose = toClose + (1) -- ./compiler/lua54.can:394 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 -if # lets > 0 then -- ./compiler/lua54.can:402 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 -toClose = toClose + (1) -- ./compiler/lua54.can:404 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 -end -- ./compiler/lua54.can:406 -else -- ./compiler/lua54.can:406 -r = r .. ("else") -- ./compiler/lua54.can:409 -end -- ./compiler/lua54.can:409 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 +end -- ./compiler/lua54.can:371 +return r -- ./compiler/lua54.can:373 +end, -- ./compiler/lua54.can:373 +["Repeat"] = function(t) -- ./compiler/lua54.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 +local r = "repeat" .. indent() -- ./compiler/lua54.can:378 +if hasContinue then -- ./compiler/lua54.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 +end -- ./compiler/lua54.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 +if hasContinue then -- ./compiler/lua54.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 +end -- ./compiler/lua54.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 +return r -- ./compiler/lua54.can:387 +end, -- ./compiler/lua54.can:387 +["If"] = function(t) -- ./compiler/lua54.can:390 +local r = "" -- ./compiler/lua54.can:391 +local toClose = 0 -- ./compiler/lua54.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 +if # lets > 0 then -- ./compiler/lua54.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 +toClose = toClose + (1) -- ./compiler/lua54.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 +if # lets > 0 then -- ./compiler/lua54.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 +toClose = toClose + (1) -- ./compiler/lua54.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +else -- ./compiler/lua54.can:408 +r = r .. ("else") -- ./compiler/lua54.can:411 end -- ./compiler/lua54.can:411 -if # t % 2 == 1 then -- ./compiler/lua54.can:413 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 -end -- ./compiler/lua54.can:414 -r = r .. ("end") -- ./compiler/lua54.can:416 -for i = 1, toClose do -- ./compiler/lua54.can:417 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 -end -- ./compiler/lua54.can:418 -return r -- ./compiler/lua54.can:420 -end, -- ./compiler/lua54.can:420 -["Fornum"] = function(t) -- ./compiler/lua54.can:423 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 -if # t == 5 then -- ./compiler/lua54.can:425 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 -if hasContinue then -- ./compiler/lua54.can:428 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 -end -- ./compiler/lua54.can:429 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 -if hasContinue then -- ./compiler/lua54.can:432 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 -end -- ./compiler/lua54.can:433 -return r .. unindent() .. "end" -- ./compiler/lua54.can:435 -else -- ./compiler/lua54.can:435 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 -if hasContinue then -- ./compiler/lua54.can:439 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 -end -- ./compiler/lua54.can:440 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 -if hasContinue then -- ./compiler/lua54.can:443 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 -end -- ./compiler/lua54.can:444 -return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 +end -- ./compiler/lua54.can:413 +if # t % 2 == 1 then -- ./compiler/lua54.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 +end -- ./compiler/lua54.can:416 +r = r .. ("end") -- ./compiler/lua54.can:418 +for i = 1, toClose do -- ./compiler/lua54.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 +end -- ./compiler/lua54.can:420 +return r -- ./compiler/lua54.can:422 +end, -- ./compiler/lua54.can:422 +["Fornum"] = function(t) -- ./compiler/lua54.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 +if # t == 5 then -- ./compiler/lua54.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 +if hasContinue then -- ./compiler/lua54.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 +end -- ./compiler/lua54.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 +if hasContinue then -- ./compiler/lua54.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 +end -- ./compiler/lua54.can:435 +return r .. unindent() .. "end" -- ./compiler/lua54.can:437 +else -- ./compiler/lua54.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 +if hasContinue then -- ./compiler/lua54.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 +end -- ./compiler/lua54.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 +if hasContinue then -- ./compiler/lua54.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 end -- ./compiler/lua54.can:446 -end, -- ./compiler/lua54.can:446 -["Forin"] = function(t) -- ./compiler/lua54.can:450 -local destructured = {} -- ./compiler/lua54.can:451 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 -if hasContinue then -- ./compiler/lua54.can:454 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 -end -- ./compiler/lua54.can:455 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 -if hasContinue then -- ./compiler/lua54.can:458 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 -end -- ./compiler/lua54.can:459 -return r .. unindent() .. "end" -- ./compiler/lua54.can:461 -end, -- ./compiler/lua54.can:461 -["Local"] = function(t) -- ./compiler/lua54.can:464 -local destructured = {} -- ./compiler/lua54.can:465 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 -if t[2][1] then -- ./compiler/lua54.can:467 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 -end -- ./compiler/lua54.can:468 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 -end, -- ./compiler/lua54.can:470 -["Let"] = function(t) -- ./compiler/lua54.can:473 -local destructured = {} -- ./compiler/lua54.can:474 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 -local r = "local " .. nameList -- ./compiler/lua54.can:476 -if t[2][1] then -- ./compiler/lua54.can:477 -if all(t[2], { -- ./compiler/lua54.can:478 -"Nil", -- ./compiler/lua54.can:478 -"Dots", -- ./compiler/lua54.can:478 -"Boolean", -- ./compiler/lua54.can:478 -"Number", -- ./compiler/lua54.can:478 -"String" -- ./compiler/lua54.can:478 -}) then -- ./compiler/lua54.can:478 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 -else -- ./compiler/lua54.can:479 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 -end, -- ./compiler/lua54.can:484 -["Localrec"] = function(t) -- ./compiler/lua54.can:487 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 -end, -- ./compiler/lua54.can:488 -["Goto"] = function(t) -- ./compiler/lua54.can:491 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 -end, -- ./compiler/lua54.can:492 -["Label"] = function(t) -- ./compiler/lua54.can:495 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 -end, -- ./compiler/lua54.can:496 -["Return"] = function(t) -- ./compiler/lua54.can:499 -local push = peek("push") -- ./compiler/lua54.can:500 -if push then -- ./compiler/lua54.can:501 -local r = "" -- ./compiler/lua54.can:502 -for _, val in ipairs(t) do -- ./compiler/lua54.can:503 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 -end -- ./compiler/lua54.can:504 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 -else -- ./compiler/lua54.can:506 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 -end -- ./compiler/lua54.can:508 -end, -- ./compiler/lua54.can:508 -["Push"] = function(t) -- ./compiler/lua54.can:512 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 -r = "" -- ./compiler/lua54.can:514 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -if t[# t] then -- ./compiler/lua54.can:518 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 -else -- ./compiler/lua54.can:520 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -return r -- ./compiler/lua54.can:525 -end, -- ./compiler/lua54.can:525 -["Break"] = function() -- ./compiler/lua54.can:528 -return "break" -- ./compiler/lua54.can:529 -end, -- ./compiler/lua54.can:529 -["Continue"] = function() -- ./compiler/lua54.can:532 -return "goto " .. var("continue") -- ./compiler/lua54.can:533 -end, -- ./compiler/lua54.can:533 -["Nil"] = function() -- ./compiler/lua54.can:540 -return "nil" -- ./compiler/lua54.can:541 -end, -- ./compiler/lua54.can:541 -["Dots"] = function() -- ./compiler/lua54.can:544 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 -return r -- ./compiler/lua54.can:550 -else -- ./compiler/lua54.can:550 -return "..." -- ./compiler/lua54.can:552 -end -- ./compiler/lua54.can:552 -end, -- ./compiler/lua54.can:552 -["Boolean"] = function(t) -- ./compiler/lua54.can:556 -return tostring(t[1]) -- ./compiler/lua54.can:557 -end, -- ./compiler/lua54.can:557 -["Number"] = function(t) -- ./compiler/lua54.can:560 -return tostring(t[1]) -- ./compiler/lua54.can:561 -end, -- ./compiler/lua54.can:561 -["String"] = function(t) -- ./compiler/lua54.can:564 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 -end, -- ./compiler/lua54.can:565 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 -local r = "(" -- ./compiler/lua54.can:569 -local decl = {} -- ./compiler/lua54.can:570 -if t[1][1] then -- ./compiler/lua54.can:571 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 -r = r .. (id) -- ./compiler/lua54.can:577 -else -- ./compiler/lua54.can:577 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 -end -- ./compiler/lua54.can:579 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 -r = r .. (", " .. id) -- ./compiler/lua54.can:587 -else -- ./compiler/lua54.can:587 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 -r = r .. (d .. newline()) -- ./compiler/lua54.can:595 -end -- ./compiler/lua54.can:595 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 -end -- ./compiler/lua54.can:598 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 -if hasPush then -- ./compiler/lua54.can:601 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 -else -- ./compiler/lua54.can:602 -push("push", false) -- ./compiler/lua54.can:604 -end -- ./compiler/lua54.can:604 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 -end -- ./compiler/lua54.can:608 -pop("push") -- ./compiler/lua54.can:610 -return r .. unindent() .. "end" -- ./compiler/lua54.can:611 -end, -- ./compiler/lua54.can:611 -["Function"] = function(t) -- ./compiler/lua54.can:613 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 -end, -- ./compiler/lua54.can:614 -["Pair"] = function(t) -- ./compiler/lua54.can:617 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 -end, -- ./compiler/lua54.can:618 -["Table"] = function(t) -- ./compiler/lua54.can:620 -if # t == 0 then -- ./compiler/lua54.can:621 -return "{}" -- ./compiler/lua54.can:622 -elseif # t == 1 then -- ./compiler/lua54.can:623 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 -else -- ./compiler/lua54.can:624 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 -end -- ./compiler/lua54.can:626 -end, -- ./compiler/lua54.can:626 -["TableCompr"] = function(t) -- ./compiler/lua54.can:630 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 -end, -- ./compiler/lua54.can:631 -["Op"] = function(t) -- ./compiler/lua54.can:634 -local r -- ./compiler/lua54.can:635 -if # t == 2 then -- ./compiler/lua54.can:636 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 -else -- ./compiler/lua54.can:638 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 -end -- ./compiler/lua54.can:640 +return r .. unindent() .. "end" -- ./compiler/lua54.can:448 +end -- ./compiler/lua54.can:448 +end, -- ./compiler/lua54.can:448 +["Forin"] = function(t) -- ./compiler/lua54.can:452 +local destructured = {} -- ./compiler/lua54.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 +if hasContinue then -- ./compiler/lua54.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 +end -- ./compiler/lua54.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 +if hasContinue then -- ./compiler/lua54.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 +end -- ./compiler/lua54.can:461 +return r .. unindent() .. "end" -- ./compiler/lua54.can:463 +end, -- ./compiler/lua54.can:463 +["Local"] = function(t) -- ./compiler/lua54.can:466 +local destructured = {} -- ./compiler/lua54.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 +if t[2][1] then -- ./compiler/lua54.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 +end -- ./compiler/lua54.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 +end, -- ./compiler/lua54.can:472 +["Let"] = function(t) -- ./compiler/lua54.can:475 +local destructured = {} -- ./compiler/lua54.can:476 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 +local r = "local " .. nameList -- ./compiler/lua54.can:478 +if t[2][1] then -- ./compiler/lua54.can:479 +if all(t[2], { -- ./compiler/lua54.can:480 +"Nil", -- ./compiler/lua54.can:480 +"Dots", -- ./compiler/lua54.can:480 +"Boolean", -- ./compiler/lua54.can:480 +"Number", -- ./compiler/lua54.can:480 +"String" -- ./compiler/lua54.can:480 +}) then -- ./compiler/lua54.can:480 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +else -- ./compiler/lua54.can:481 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Localrec"] = function(t) -- ./compiler/lua54.can:489 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Goto"] = function(t) -- ./compiler/lua54.can:493 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 +end, -- ./compiler/lua54.can:494 +["Label"] = function(t) -- ./compiler/lua54.can:497 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 +end, -- ./compiler/lua54.can:498 +["Return"] = function(t) -- ./compiler/lua54.can:501 +local push = peek("push") -- ./compiler/lua54.can:502 +if push then -- ./compiler/lua54.can:503 +local r = "" -- ./compiler/lua54.can:504 +for _, val in ipairs(t) do -- ./compiler/lua54.can:505 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 +end -- ./compiler/lua54.can:506 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 +else -- ./compiler/lua54.can:508 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +end, -- ./compiler/lua54.can:510 +["Push"] = function(t) -- ./compiler/lua54.can:514 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 +r = "" -- ./compiler/lua54.can:516 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 +end -- ./compiler/lua54.can:518 +if t[# t] then -- ./compiler/lua54.can:520 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 +else -- ./compiler/lua54.can:522 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +return r -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Break"] = function() -- ./compiler/lua54.can:530 +return "break" -- ./compiler/lua54.can:531 +end, -- ./compiler/lua54.can:531 +["Continue"] = function() -- ./compiler/lua54.can:534 +return "goto " .. var("continue") -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Nil"] = function() -- ./compiler/lua54.can:542 +return "nil" -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Dots"] = function() -- ./compiler/lua54.can:546 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 +return r -- ./compiler/lua54.can:552 +else -- ./compiler/lua54.can:552 +return "..." -- ./compiler/lua54.can:554 +end -- ./compiler/lua54.can:554 +end, -- ./compiler/lua54.can:554 +["Boolean"] = function(t) -- ./compiler/lua54.can:558 +return tostring(t[1]) -- ./compiler/lua54.can:559 +end, -- ./compiler/lua54.can:559 +["Number"] = function(t) -- ./compiler/lua54.can:562 +return tostring(t[1]) -- ./compiler/lua54.can:563 +end, -- ./compiler/lua54.can:563 +["String"] = function(t) -- ./compiler/lua54.can:566 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 +end, -- ./compiler/lua54.can:567 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 +local r = "(" -- ./compiler/lua54.can:571 +local decl = {} -- ./compiler/lua54.can:572 +if t[1][1] then -- ./compiler/lua54.can:573 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 +r = r .. (id) -- ./compiler/lua54.can:579 +else -- ./compiler/lua54.can:579 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 +r = r .. (", " .. id) -- ./compiler/lua54.can:589 +else -- ./compiler/lua54.can:589 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 +r = r .. (d .. newline()) -- ./compiler/lua54.can:597 +end -- ./compiler/lua54.can:597 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 +end -- ./compiler/lua54.can:600 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 +if hasPush then -- ./compiler/lua54.can:603 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 +else -- ./compiler/lua54.can:604 +push("push", false) -- ./compiler/lua54.can:606 +end -- ./compiler/lua54.can:606 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 +end -- ./compiler/lua54.can:610 +pop("push") -- ./compiler/lua54.can:612 +return r .. unindent() .. "end" -- ./compiler/lua54.can:613 +end, -- ./compiler/lua54.can:613 +["Function"] = function(t) -- ./compiler/lua54.can:615 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 +end, -- ./compiler/lua54.can:616 +["Pair"] = function(t) -- ./compiler/lua54.can:619 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 +end, -- ./compiler/lua54.can:620 +["Table"] = function(t) -- ./compiler/lua54.can:622 +if # t == 0 then -- ./compiler/lua54.can:623 +return "{}" -- ./compiler/lua54.can:624 +elseif # t == 1 then -- ./compiler/lua54.can:625 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 +end -- ./compiler/lua54.can:628 +end, -- ./compiler/lua54.can:628 +["TableCompr"] = function(t) -- ./compiler/lua54.can:632 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 +end, -- ./compiler/lua54.can:633 +["Op"] = function(t) -- ./compiler/lua54.can:636 +local r -- ./compiler/lua54.can:637 +if # t == 2 then -- ./compiler/lua54.can:638 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 else -- ./compiler/lua54.can:640 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 -else -- ./compiler/lua54.can:644 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -return r -- ./compiler/lua54.can:649 -end, -- ./compiler/lua54.can:649 -["Paren"] = function(t) -- ./compiler/lua54.can:652 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 -end, -- ./compiler/lua54.can:653 -["MethodStub"] = function(t) -- ./compiler/lua54.can:656 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 -end, -- ./compiler/lua54.can:662 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 -end, -- ./compiler/lua54.can:672 -["LetExpr"] = function(t) -- ./compiler/lua54.can:679 -return lua(t[1][1]) -- ./compiler/lua54.can:680 -end, -- ./compiler/lua54.can:680 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 -local r = "(function()" .. indent() -- ./compiler/lua54.can:686 -if hasPush then -- ./compiler/lua54.can:687 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 -else -- ./compiler/lua54.can:688 -push("push", false) -- ./compiler/lua54.can:690 -end -- ./compiler/lua54.can:690 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 -if hasPush then -- ./compiler/lua54.can:693 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 -end -- ./compiler/lua54.can:694 -pop("push") -- ./compiler/lua54.can:696 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 -return r -- ./compiler/lua54.can:698 -end, -- ./compiler/lua54.can:698 -["DoExpr"] = function(t) -- ./compiler/lua54.can:701 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 -end -- ./compiler/lua54.can:703 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 -end, -- ./compiler/lua54.can:705 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 -end, -- ./compiler/lua54.can:709 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 -end, -- ./compiler/lua54.can:713 -["IfExpr"] = function(t) -- ./compiler/lua54.can:716 -for i = 2, # t do -- ./compiler/lua54.can:717 -local block = t[i] -- ./compiler/lua54.can:718 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 -end, -- ./compiler/lua54.can:723 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 -end, -- ./compiler/lua54.can:727 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 -end, -- ./compiler/lua54.can:731 -["Call"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 -local replacement = macro["replacement"] -- ./compiler/lua54.can:742 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 -macroargs["..."] = (function() -- ./compiler/lua54.can:746 -local self = {} -- ./compiler/lua54.can:746 -for j = i + 1, # t do -- ./compiler/lua54.can:746 -self[#self+1] = t[j] -- ./compiler/lua54.can:746 -end -- ./compiler/lua54.can:746 -return self -- ./compiler/lua54.can:746 -end)() -- ./compiler/lua54.can:746 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 -if t[i + 1] == nil then -- ./compiler/lua54.can:748 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 -end -- ./compiler/lua54.can:749 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 -else -- ./compiler/lua54.can:751 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -push("macroargs", macroargs) -- ./compiler/lua54.can:756 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 -local r = lua(replacement) -- ./compiler/lua54.can:758 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 -pop("macroargs") -- ./compiler/lua54.can:760 -return r -- ./compiler/lua54.can:761 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 -else -- ./compiler/lua54.can:764 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 -end -- ./compiler/lua54.can:766 -else -- ./compiler/lua54.can:766 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 +end -- ./compiler/lua54.can:642 +else -- ./compiler/lua54.can:642 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 +else -- ./compiler/lua54.can:646 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +return r -- ./compiler/lua54.can:651 +end, -- ./compiler/lua54.can:651 +["Paren"] = function(t) -- ./compiler/lua54.can:654 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 +end, -- ./compiler/lua54.can:655 +["MethodStub"] = function(t) -- ./compiler/lua54.can:658 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 +end, -- ./compiler/lua54.can:664 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 +end, -- ./compiler/lua54.can:674 +["LetExpr"] = function(t) -- ./compiler/lua54.can:681 +return lua(t[1][1]) -- ./compiler/lua54.can:682 +end, -- ./compiler/lua54.can:682 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 +local r = "(function()" .. indent() -- ./compiler/lua54.can:688 +if hasPush then -- ./compiler/lua54.can:689 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 +else -- ./compiler/lua54.can:690 +push("push", false) -- ./compiler/lua54.can:692 +end -- ./compiler/lua54.can:692 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 +if hasPush then -- ./compiler/lua54.can:695 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 +end -- ./compiler/lua54.can:696 +pop("push") -- ./compiler/lua54.can:698 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 +return r -- ./compiler/lua54.can:700 +end, -- ./compiler/lua54.can:700 +["DoExpr"] = function(t) -- ./compiler/lua54.can:703 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 +end -- ./compiler/lua54.can:705 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 +end, -- ./compiler/lua54.can:707 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 +end, -- ./compiler/lua54.can:711 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 +end, -- ./compiler/lua54.can:715 +["IfExpr"] = function(t) -- ./compiler/lua54.can:718 +for i = 2, # t do -- ./compiler/lua54.can:719 +local block = t[i] -- ./compiler/lua54.can:720 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 +end, -- ./compiler/lua54.can:725 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 +end, -- ./compiler/lua54.can:729 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["Call"] = function(t) -- ./compiler/lua54.can:739 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 +local replacement = macro["replacement"] -- ./compiler/lua54.can:744 +local r -- ./compiler/lua54.can:745 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 +if type(replacement) == "function" then -- ./compiler/lua54.can:747 +local args = {} -- ./compiler/lua54.can:748 +for i = 2, # t do -- ./compiler/lua54.can:749 +table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 +end -- ./compiler/lua54.can:750 +r = replacement(unpack(args)) -- ./compiler/lua54.can:752 +else -- ./compiler/lua54.can:752 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 +macroargs["..."] = (function() -- ./compiler/lua54.can:757 +local self = {} -- ./compiler/lua54.can:757 +for j = i + 1, # t do -- ./compiler/lua54.can:757 +self[#self+1] = t[j] -- ./compiler/lua54.can:757 +end -- ./compiler/lua54.can:757 +return self -- ./compiler/lua54.can:757 +end)() -- ./compiler/lua54.can:757 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 +if t[i + 1] == nil then -- ./compiler/lua54.can:759 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 +end -- ./compiler/lua54.can:760 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 +else -- ./compiler/lua54.can:762 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +push("macroargs", macroargs) -- ./compiler/lua54.can:767 +r = lua(replacement) -- ./compiler/lua54.can:768 +pop("macroargs") -- ./compiler/lua54.can:769 end -- ./compiler/lua54.can:769 -end, -- ./compiler/lua54.can:769 -["SafeCall"] = function(t) -- ./compiler/lua54.can:773 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 +return r -- ./compiler/lua54.can:772 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 else -- ./compiler/lua54.can:775 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 end -- ./compiler/lua54.can:777 -end, -- ./compiler/lua54.can:777 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 -if start == nil then start = 1 end -- ./compiler/lua54.can:782 -local r -- ./compiler/lua54.can:783 -if t[start] then -- ./compiler/lua54.can:784 -r = lua(t[start]) -- ./compiler/lua54.can:785 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 -end -- ./compiler/lua54.can:787 -else -- ./compiler/lua54.can:787 -r = "" -- ./compiler/lua54.can:790 -end -- ./compiler/lua54.can:790 -return r -- ./compiler/lua54.can:792 -end, -- ./compiler/lua54.can:792 -["Id"] = function(t) -- ./compiler/lua54.can:795 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 -local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:802 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 -local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 -return r -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -return t[1] -- ./compiler/lua54.can:810 -end, -- ./compiler/lua54.can:810 -["AttributeId"] = function(t) -- ./compiler/lua54.can:813 -if t[2] then -- ./compiler/lua54.can:814 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 -else -- ./compiler/lua54.can:815 -return t[1] -- ./compiler/lua54.can:817 -end -- ./compiler/lua54.can:817 -end, -- ./compiler/lua54.can:817 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 -if t["id"] then -- ./compiler/lua54.can:822 -return t["id"] -- ./compiler/lua54.can:823 -else -- ./compiler/lua54.can:823 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 -for j = 1, # t, 1 do -- ./compiler/lua54.can:827 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 -end -- ./compiler/lua54.can:828 -table["insert"](d, vars) -- ./compiler/lua54.can:830 -t["id"] = vars["id"] -- ./compiler/lua54.can:831 -return vars["id"] -- ./compiler/lua54.can:832 -end -- ./compiler/lua54.can:832 -end, -- ./compiler/lua54.can:832 -["Index"] = function(t) -- ./compiler/lua54.can:836 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 -else -- ./compiler/lua54.can:838 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 -end -- ./compiler/lua54.can:840 -end, -- ./compiler/lua54.can:840 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 -local l = {} -- ./compiler/lua54.can:846 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 -table["insert"](l, 1, t) -- ./compiler/lua54.can:848 -t = t[1] -- ./compiler/lua54.can:849 -end -- ./compiler/lua54.can:849 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 -for _, e in ipairs(l) do -- ./compiler/lua54.can:852 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 -else -- ./compiler/lua54.can:855 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 -return r -- ./compiler/lua54.can:861 -else -- ./compiler/lua54.can:861 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 -end -- ./compiler/lua54.can:863 -end, -- ./compiler/lua54.can:863 -["_opid"] = { -- ./compiler/lua54.can:868 -["add"] = "+", -- ./compiler/lua54.can:869 -["sub"] = "-", -- ./compiler/lua54.can:869 -["mul"] = "*", -- ./compiler/lua54.can:869 -["div"] = "/", -- ./compiler/lua54.can:869 -["idiv"] = "//", -- ./compiler/lua54.can:870 -["mod"] = "%", -- ./compiler/lua54.can:870 -["pow"] = "^", -- ./compiler/lua54.can:870 -["concat"] = "..", -- ./compiler/lua54.can:870 -["band"] = "&", -- ./compiler/lua54.can:871 -["bor"] = "|", -- ./compiler/lua54.can:871 -["bxor"] = "~", -- ./compiler/lua54.can:871 -["shl"] = "<<", -- ./compiler/lua54.can:871 -["shr"] = ">>", -- ./compiler/lua54.can:871 -["eq"] = "==", -- ./compiler/lua54.can:872 -["ne"] = "~=", -- ./compiler/lua54.can:872 -["lt"] = "<", -- ./compiler/lua54.can:872 -["gt"] = ">", -- ./compiler/lua54.can:872 -["le"] = "<=", -- ./compiler/lua54.can:872 -["ge"] = ">=", -- ./compiler/lua54.can:872 -["and"] = "and", -- ./compiler/lua54.can:873 -["or"] = "or", -- ./compiler/lua54.can:873 -["unm"] = "-", -- ./compiler/lua54.can:873 -["len"] = "#", -- ./compiler/lua54.can:873 -["bnot"] = "~", -- ./compiler/lua54.can:873 -["not"] = "not" -- ./compiler/lua54.can:873 -} -- ./compiler/lua54.can:873 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 -end }) -- ./compiler/lua54.can:877 +else -- ./compiler/lua54.can:777 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 +end -- ./compiler/lua54.can:780 +end, -- ./compiler/lua54.can:780 +["SafeCall"] = function(t) -- ./compiler/lua54.can:784 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 +else -- ./compiler/lua54.can:786 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 +end -- ./compiler/lua54.can:788 +end, -- ./compiler/lua54.can:788 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 +if start == nil then start = 1 end -- ./compiler/lua54.can:793 +local r -- ./compiler/lua54.can:794 +if t[start] then -- ./compiler/lua54.can:795 +r = lua(t[start]) -- ./compiler/lua54.can:796 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 +end -- ./compiler/lua54.can:798 +else -- ./compiler/lua54.can:798 +r = "" -- ./compiler/lua54.can:801 +end -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:803 +end, -- ./compiler/lua54.can:803 +["Id"] = function(t) -- ./compiler/lua54.can:806 +local r = t[1] -- ./compiler/lua54.can:807 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 +r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 +local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 +if type(macro) == "function" then -- ./compiler/lua54.can:815 +r = macro() -- ./compiler/lua54.can:816 +else -- ./compiler/lua54.can:816 +r = lua(macro) -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 +end -- ./compiler/lua54.can:821 +return r -- ./compiler/lua54.can:823 +end, -- ./compiler/lua54.can:823 +["AttributeId"] = function(t) -- ./compiler/lua54.can:826 +if t[2] then -- ./compiler/lua54.can:827 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 +else -- ./compiler/lua54.can:828 +return t[1] -- ./compiler/lua54.can:830 +end -- ./compiler/lua54.can:830 +end, -- ./compiler/lua54.can:830 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 +if t["id"] then -- ./compiler/lua54.can:835 +return t["id"] -- ./compiler/lua54.can:836 +else -- ./compiler/lua54.can:836 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 +for j = 1, # t, 1 do -- ./compiler/lua54.can:840 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 +end -- ./compiler/lua54.can:841 +table["insert"](d, vars) -- ./compiler/lua54.can:843 +t["id"] = vars["id"] -- ./compiler/lua54.can:844 +return vars["id"] -- ./compiler/lua54.can:845 +end -- ./compiler/lua54.can:845 +end, -- ./compiler/lua54.can:845 +["Index"] = function(t) -- ./compiler/lua54.can:849 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 +else -- ./compiler/lua54.can:851 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 +end -- ./compiler/lua54.can:853 +end, -- ./compiler/lua54.can:853 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 +local l = {} -- ./compiler/lua54.can:859 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 +table["insert"](l, 1, t) -- ./compiler/lua54.can:861 +t = t[1] -- ./compiler/lua54.can:862 +end -- ./compiler/lua54.can:862 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 +for _, e in ipairs(l) do -- ./compiler/lua54.can:865 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 +else -- ./compiler/lua54.can:868 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 +return r -- ./compiler/lua54.can:874 +else -- ./compiler/lua54.can:874 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 +end -- ./compiler/lua54.can:876 +end, -- ./compiler/lua54.can:876 +["_opid"] = { -- ./compiler/lua54.can:881 +["add"] = "+", -- ./compiler/lua54.can:882 +["sub"] = "-", -- ./compiler/lua54.can:882 +["mul"] = "*", -- ./compiler/lua54.can:882 +["div"] = "/", -- ./compiler/lua54.can:882 +["idiv"] = "//", -- ./compiler/lua54.can:883 +["mod"] = "%", -- ./compiler/lua54.can:883 +["pow"] = "^", -- ./compiler/lua54.can:883 +["concat"] = "..", -- ./compiler/lua54.can:883 +["band"] = "&", -- ./compiler/lua54.can:884 +["bor"] = "|", -- ./compiler/lua54.can:884 +["bxor"] = "~", -- ./compiler/lua54.can:884 +["shl"] = "<<", -- ./compiler/lua54.can:884 +["shr"] = ">>", -- ./compiler/lua54.can:884 +["eq"] = "==", -- ./compiler/lua54.can:885 +["ne"] = "~=", -- ./compiler/lua54.can:885 +["lt"] = "<", -- ./compiler/lua54.can:885 +["gt"] = ">", -- ./compiler/lua54.can:885 +["le"] = "<=", -- ./compiler/lua54.can:885 +["ge"] = ">=", -- ./compiler/lua54.can:885 +["and"] = "and", -- ./compiler/lua54.can:886 +["or"] = "or", -- ./compiler/lua54.can:886 +["unm"] = "-", -- ./compiler/lua54.can:886 +["len"] = "#", -- ./compiler/lua54.can:886 +["bnot"] = "~", -- ./compiler/lua54.can:886 +["not"] = "not" -- ./compiler/lua54.can:886 +} -- ./compiler/lua54.can:886 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 +end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -2948,11 +2984,11 @@ end -- ./compiler/lua52.can:23 tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 end -- ./compiler/lua52.can:26 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 -return requireStr .. code -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -local lua54 = _() or lua54 -- ./compiler/lua54.can:889 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 +return requireStr .. code -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +local lua54 = _() or lua54 -- ./compiler/lua54.can:902 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -2966,919 +3002,931 @@ local function _() -- ./compiler/lua52.can:47 local function _() -- ./compiler/lua52.can:49 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -return function(code, ast, options, macros) -- ./compiler/lua54.can:5 -if macros == nil then macros = { -- ./compiler/lua54.can:5 -["functions"] = {}, -- ./compiler/lua54.can:5 -["variables"] = {} -- ./compiler/lua54.can:5 -} end -- ./compiler/lua54.can:5 -local lastInputPos = 1 -- ./compiler/lua54.can:7 -local prevLinePos = 1 -- ./compiler/lua54.can:8 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 -local lastLine = 1 -- ./compiler/lua54.can:10 -local indentLevel = 0 -- ./compiler/lua54.can:13 -local function newline() -- ./compiler/lua54.can:15 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 -if options["mapLines"] then -- ./compiler/lua54.can:17 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 +local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 +return function(code, ast, options, macros) -- ./compiler/lua54.can:7 +if macros == nil then macros = { -- ./compiler/lua54.can:7 +["functions"] = {}, -- ./compiler/lua54.can:7 +["variables"] = {} -- ./compiler/lua54.can:7 +} end -- ./compiler/lua54.can:7 +local lastInputPos = 1 -- ./compiler/lua54.can:9 +local prevLinePos = 1 -- ./compiler/lua54.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 +local lastLine = 1 -- ./compiler/lua54.can:12 +local indentLevel = 0 -- ./compiler/lua54.can:15 +local function newline() -- ./compiler/lua54.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 +if options["mapLines"] then -- ./compiler/lua54.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:19 -if source and line then -- ./compiler/lua54.can:21 -lastSource = source -- ./compiler/lua54.can:22 -lastLine = tonumber(line) -- ./compiler/lua54.can:23 -else -- ./compiler/lua54.can:23 +") -- ./compiler/lua54.can:21 +if source and line then -- ./compiler/lua54.can:23 +lastSource = source -- ./compiler/lua54.can:24 +lastLine = tonumber(line) -- ./compiler/lua54.can:25 +else -- ./compiler/lua54.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:25 -lastLine = lastLine + (1) -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -prevLinePos = lastInputPos -- ./compiler/lua54.can:30 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 -end -- ./compiler/lua54.can:32 -return r -- ./compiler/lua54.can:34 +") do -- ./compiler/lua54.can:27 +lastLine = lastLine + (1) -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +prevLinePos = lastInputPos -- ./compiler/lua54.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 end -- ./compiler/lua54.can:34 -local function indent() -- ./compiler/lua54.can:37 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 -return newline() -- ./compiler/lua54.can:39 -end -- ./compiler/lua54.can:39 -local function unindent() -- ./compiler/lua54.can:42 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 -return newline() -- ./compiler/lua54.can:44 -end -- ./compiler/lua54.can:44 -local states = { -- ./compiler/lua54.can:49 -["push"] = {}, -- ./compiler/lua54.can:50 -["destructuring"] = {}, -- ./compiler/lua54.can:51 -["scope"] = {}, -- ./compiler/lua54.can:52 -["macroargs"] = {} -- ./compiler/lua54.can:53 -} -- ./compiler/lua54.can:53 -local function push(name, state) -- ./compiler/lua54.can:56 -table["insert"](states[name], state) -- ./compiler/lua54.can:57 -return "" -- ./compiler/lua54.can:58 -end -- ./compiler/lua54.can:58 -local function pop(name) -- ./compiler/lua54.can:61 -table["remove"](states[name]) -- ./compiler/lua54.can:62 -return "" -- ./compiler/lua54.can:63 -end -- ./compiler/lua54.can:63 -local function set(name, state) -- ./compiler/lua54.can:66 -states[name][# states[name]] = state -- ./compiler/lua54.can:67 -return "" -- ./compiler/lua54.can:68 -end -- ./compiler/lua54.can:68 -local function peek(name) -- ./compiler/lua54.can:71 -return states[name][# states[name]] -- ./compiler/lua54.can:72 -end -- ./compiler/lua54.can:72 -local function var(name) -- ./compiler/lua54.can:77 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 -end -- ./compiler/lua54.can:78 -local function tmp() -- ./compiler/lua54.can:82 -local scope = peek("scope") -- ./compiler/lua54.can:83 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 -table["insert"](scope, var) -- ./compiler/lua54.can:85 -return var -- ./compiler/lua54.can:86 -end -- ./compiler/lua54.can:86 -local nomacro = { -- ./compiler/lua54.can:90 -["variables"] = {}, -- ./compiler/lua54.can:90 -["functions"] = {} -- ./compiler/lua54.can:90 -} -- ./compiler/lua54.can:90 -local required = {} -- ./compiler/lua54.can:93 -local requireStr = "" -- ./compiler/lua54.can:94 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 -if not required[req] then -- ./compiler/lua54.can:98 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 -required[req] = true -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -local loop = { -- ./compiler/lua54.can:105 -"While", -- ./compiler/lua54.can:105 -"Repeat", -- ./compiler/lua54.can:105 -"Fornum", -- ./compiler/lua54.can:105 -"Forin", -- ./compiler/lua54.can:105 -"WhileExpr", -- ./compiler/lua54.can:105 -"RepeatExpr", -- ./compiler/lua54.can:105 -"FornumExpr", -- ./compiler/lua54.can:105 -"ForinExpr" -- ./compiler/lua54.can:105 -} -- ./compiler/lua54.can:105 -local func = { -- ./compiler/lua54.can:106 -"Function", -- ./compiler/lua54.can:106 -"TableCompr", -- ./compiler/lua54.can:106 -"DoExpr", -- ./compiler/lua54.can:106 -"WhileExpr", -- ./compiler/lua54.can:106 -"RepeatExpr", -- ./compiler/lua54.can:106 -"IfExpr", -- ./compiler/lua54.can:106 -"FornumExpr", -- ./compiler/lua54.can:106 -"ForinExpr" -- ./compiler/lua54.can:106 -} -- ./compiler/lua54.can:106 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 -local tagsCheck = {} -- ./compiler/lua54.can:111 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 -tagsCheck[tag] = true -- ./compiler/lua54.can:113 -end -- ./compiler/lua54.can:113 -local nofollowCheck = {} -- ./compiler/lua54.can:115 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 -nofollowCheck[tag] = true -- ./compiler/lua54.can:117 -end -- ./compiler/lua54.can:117 -for _, node in ipairs(list) do -- ./compiler/lua54.can:119 -if type(node) == "table" then -- ./compiler/lua54.can:120 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 -return node -- ./compiler/lua54.can:122 -end -- ./compiler/lua54.can:122 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 -if r then -- ./compiler/lua54.can:126 -return r -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -return nil -- ./compiler/lua54.can:130 -end -- ./compiler/lua54.can:130 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 -local tagsCheck = {} -- ./compiler/lua54.can:136 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 -tagsCheck[tag] = true -- ./compiler/lua54.can:138 -end -- ./compiler/lua54.can:138 -local nofollowCheck = {} -- ./compiler/lua54.can:140 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 -nofollowCheck[tag] = true -- ./compiler/lua54.can:142 -end -- ./compiler/lua54.can:142 -local found = {} -- ./compiler/lua54.can:144 -for _, node in ipairs(list) do -- ./compiler/lua54.can:145 -if type(node) == "table" then -- ./compiler/lua54.can:146 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 -table["insert"](found, n) -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 -table["insert"](found, node) -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -return found -- ./compiler/lua54.can:157 -end -- ./compiler/lua54.can:157 -local function all(list, tags) -- ./compiler/lua54.can:161 -for _, node in ipairs(list) do -- ./compiler/lua54.can:162 -local ok = false -- ./compiler/lua54.can:163 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 -if node["tag"] == tag then -- ./compiler/lua54.can:165 -ok = true -- ./compiler/lua54.can:166 -break -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -if not ok then -- ./compiler/lua54.can:170 -return false -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -return true -- ./compiler/lua54.can:174 -end -- ./compiler/lua54.can:174 -local tags -- ./compiler/lua54.can:178 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 -end -- ./compiler/lua54.can:182 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +return r -- ./compiler/lua54.can:36 +end -- ./compiler/lua54.can:36 +local function indent() -- ./compiler/lua54.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 +return newline() -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local function unindent() -- ./compiler/lua54.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 +return newline() -- ./compiler/lua54.can:46 +end -- ./compiler/lua54.can:46 +local states = { -- ./compiler/lua54.can:51 +["push"] = {}, -- ./compiler/lua54.can:52 +["destructuring"] = {}, -- ./compiler/lua54.can:53 +["scope"] = {}, -- ./compiler/lua54.can:54 +["macroargs"] = {} -- ./compiler/lua54.can:55 +} -- ./compiler/lua54.can:55 +local function push(name, state) -- ./compiler/lua54.can:58 +table["insert"](states[name], state) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function pop(name) -- ./compiler/lua54.can:63 +table["remove"](states[name]) -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function set(name, state) -- ./compiler/lua54.can:68 +states[name][# states[name]] = state -- ./compiler/lua54.can:69 +return "" -- ./compiler/lua54.can:70 +end -- ./compiler/lua54.can:70 +local function peek(name) -- ./compiler/lua54.can:73 +return states[name][# states[name]] -- ./compiler/lua54.can:74 +end -- ./compiler/lua54.can:74 +local function var(name) -- ./compiler/lua54.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 +end -- ./compiler/lua54.can:80 +local function tmp() -- ./compiler/lua54.can:84 +local scope = peek("scope") -- ./compiler/lua54.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 +table["insert"](scope, var) -- ./compiler/lua54.can:87 +return var -- ./compiler/lua54.can:88 +end -- ./compiler/lua54.can:88 +local nomacro = { -- ./compiler/lua54.can:92 +["variables"] = {}, -- ./compiler/lua54.can:92 +["functions"] = {} -- ./compiler/lua54.can:92 +} -- ./compiler/lua54.can:92 +local required = {} -- ./compiler/lua54.can:95 +local requireStr = "" -- ./compiler/lua54.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 +if not required[req] then -- ./compiler/lua54.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 +required[req] = true -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +local loop = { -- ./compiler/lua54.can:107 +"While", -- ./compiler/lua54.can:107 +"Repeat", -- ./compiler/lua54.can:107 +"Fornum", -- ./compiler/lua54.can:107 +"Forin", -- ./compiler/lua54.can:107 +"WhileExpr", -- ./compiler/lua54.can:107 +"RepeatExpr", -- ./compiler/lua54.can:107 +"FornumExpr", -- ./compiler/lua54.can:107 +"ForinExpr" -- ./compiler/lua54.can:107 +} -- ./compiler/lua54.can:107 +local func = { -- ./compiler/lua54.can:108 +"Function", -- ./compiler/lua54.can:108 +"TableCompr", -- ./compiler/lua54.can:108 +"DoExpr", -- ./compiler/lua54.can:108 +"WhileExpr", -- ./compiler/lua54.can:108 +"RepeatExpr", -- ./compiler/lua54.can:108 +"IfExpr", -- ./compiler/lua54.can:108 +"FornumExpr", -- ./compiler/lua54.can:108 +"ForinExpr" -- ./compiler/lua54.can:108 +} -- ./compiler/lua54.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 +local tagsCheck = {} -- ./compiler/lua54.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 +tagsCheck[tag] = true -- ./compiler/lua54.can:115 +end -- ./compiler/lua54.can:115 +local nofollowCheck = {} -- ./compiler/lua54.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 +nofollowCheck[tag] = true -- ./compiler/lua54.can:119 +end -- ./compiler/lua54.can:119 +for _, node in ipairs(list) do -- ./compiler/lua54.can:121 +if type(node) == "table" then -- ./compiler/lua54.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 +return node -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 +if r then -- ./compiler/lua54.can:128 +return r -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +return nil -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 +local tagsCheck = {} -- ./compiler/lua54.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 +tagsCheck[tag] = true -- ./compiler/lua54.can:140 +end -- ./compiler/lua54.can:140 +local nofollowCheck = {} -- ./compiler/lua54.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 +nofollowCheck[tag] = true -- ./compiler/lua54.can:144 +end -- ./compiler/lua54.can:144 +local found = {} -- ./compiler/lua54.can:146 +for _, node in ipairs(list) do -- ./compiler/lua54.can:147 +if type(node) == "table" then -- ./compiler/lua54.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 +table["insert"](found, n) -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 +table["insert"](found, node) -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +return found -- ./compiler/lua54.can:159 +end -- ./compiler/lua54.can:159 +local function all(list, tags) -- ./compiler/lua54.can:163 +for _, node in ipairs(list) do -- ./compiler/lua54.can:164 +local ok = false -- ./compiler/lua54.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 +if node["tag"] == tag then -- ./compiler/lua54.can:167 +ok = true -- ./compiler/lua54.can:168 +break -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +if not ok then -- ./compiler/lua54.can:172 +return false -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +return true -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +local tags -- ./compiler/lua54.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 end -- ./compiler/lua54.can:184 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 -end -- ./compiler/lua54.can:189 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 -end -- ./compiler/lua54.can:192 -local CONTINUE_START = function() -- ./compiler/lua54.can:194 -return "do" .. indent() -- ./compiler/lua54.can:195 -end -- ./compiler/lua54.can:195 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 -end -- ./compiler/lua54.can:198 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 -local vars = {} -- ./compiler/lua54.can:201 -local values = {} -- ./compiler/lua54.can:202 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 -for _, v in ipairs(list) do -- ./compiler/lua54.can:204 -local var, val -- ./compiler/lua54.can:205 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 -var = v -- ./compiler/lua54.can:207 -val = { -- ./compiler/lua54.can:208 -["tag"] = "Index", -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "Id", -- ./compiler/lua54.can:208 -list["id"] -- ./compiler/lua54.can:208 -}, -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "String", -- ./compiler/lua54.can:208 -v[1] -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 -var = v[2] -- ./compiler/lua54.can:210 -val = { -- ./compiler/lua54.can:211 -["tag"] = "Index", -- ./compiler/lua54.can:211 -{ -- ./compiler/lua54.can:211 -["tag"] = "Id", -- ./compiler/lua54.can:211 -list["id"] -- ./compiler/lua54.can:211 -}, -- ./compiler/lua54.can:211 -v[1] -- ./compiler/lua54.can:211 -} -- ./compiler/lua54.can:211 -else -- ./compiler/lua54.can:211 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 -end -- ./compiler/lua54.can:213 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 -val = { -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["rightOp"], -- ./compiler/lua54.can:216 -var, -- ./compiler/lua54.can:216 -{ -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["leftOp"], -- ./compiler/lua54.can:216 -val, -- ./compiler/lua54.can:216 -var -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 +end -- ./compiler/lua54.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 +end -- ./compiler/lua54.can:194 +local CONTINUE_START = function() -- ./compiler/lua54.can:196 +return "do" .. indent() -- ./compiler/lua54.can:197 +end -- ./compiler/lua54.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 +end -- ./compiler/lua54.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 +local vars = {} -- ./compiler/lua54.can:203 +local values = {} -- ./compiler/lua54.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 +for _, v in ipairs(list) do -- ./compiler/lua54.can:206 +local var, val -- ./compiler/lua54.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 +var = v -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Index", -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Id", -- ./compiler/lua54.can:210 +list["id"] -- ./compiler/lua54.can:210 +}, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "String", -- ./compiler/lua54.can:210 +v[1] -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 +var = v[2] -- ./compiler/lua54.can:212 +val = { -- ./compiler/lua54.can:213 +["tag"] = "Index", -- ./compiler/lua54.can:213 +{ -- ./compiler/lua54.can:213 +["tag"] = "Id", -- ./compiler/lua54.can:213 +list["id"] -- ./compiler/lua54.can:213 +}, -- ./compiler/lua54.can:213 +v[1] -- ./compiler/lua54.can:213 +} -- ./compiler/lua54.can:213 +else -- ./compiler/lua54.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 +end -- ./compiler/lua54.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 val = { -- ./compiler/lua54.can:218 ["tag"] = "Op", -- ./compiler/lua54.can:218 destructured["rightOp"], -- ./compiler/lua54.can:218 var, -- ./compiler/lua54.can:218 -val -- ./compiler/lua54.can:218 +{ -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["leftOp"], -- ./compiler/lua54.can:218 +val, -- ./compiler/lua54.can:218 +var -- ./compiler/lua54.can:218 } -- ./compiler/lua54.can:218 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +} -- ./compiler/lua54.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 val = { -- ./compiler/lua54.can:220 ["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["leftOp"], -- ./compiler/lua54.can:220 -val, -- ./compiler/lua54.can:220 -var -- ./compiler/lua54.can:220 +destructured["rightOp"], -- ./compiler/lua54.can:220 +var, -- ./compiler/lua54.can:220 +val -- ./compiler/lua54.can:220 } -- ./compiler/lua54.can:220 -end -- ./compiler/lua54.can:220 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -if # vars > 0 then -- ./compiler/lua54.can:226 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 -if newlineAfter then -- ./compiler/lua54.can:228 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 -else -- ./compiler/lua54.can:229 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 -end -- ./compiler/lua54.can:231 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 +val = { -- ./compiler/lua54.can:222 +["tag"] = "Op", -- ./compiler/lua54.can:222 +destructured["leftOp"], -- ./compiler/lua54.can:222 +val, -- ./compiler/lua54.can:222 +var -- ./compiler/lua54.can:222 +} -- ./compiler/lua54.can:222 +end -- ./compiler/lua54.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +if # vars > 0 then -- ./compiler/lua54.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 +if newlineAfter then -- ./compiler/lua54.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 else -- ./compiler/lua54.can:231 -return "" -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -tags = setmetatable({ -- ./compiler/lua54.can:239 -["Block"] = function(t) -- ./compiler/lua54.can:241 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 -hasPush = false -- ./compiler/lua54.can:245 -end -- ./compiler/lua54.can:245 -local r = push("scope", {}) -- ./compiler/lua54.can:247 -if hasPush then -- ./compiler/lua54.can:248 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 -end -- ./compiler/lua54.can:249 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 -end -- ./compiler/lua54.can:252 -if t[# t] then -- ./compiler/lua54.can:254 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 -end -- ./compiler/lua54.can:255 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 -end -- ./compiler/lua54.can:258 -return r .. pop("scope") -- ./compiler/lua54.can:260 -end, -- ./compiler/lua54.can:260 -["Do"] = function(t) -- ./compiler/lua54.can:266 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 -end, -- ./compiler/lua54.can:267 -["Set"] = function(t) -- ./compiler/lua54.can:270 -local expr = t[# t] -- ./compiler/lua54.can:272 -local vars, values = {}, {} -- ./compiler/lua54.can:273 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 -else -- ./compiler/lua54.can:278 -table["insert"](vars, n) -- ./compiler/lua54.can:280 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 -local r = "" -- ./compiler/lua54.can:286 -if # vars > 0 then -- ./compiler/lua54.can:287 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 -end -- ./compiler/lua54.can:288 -if # destructuringVars > 0 then -- ./compiler/lua54.can:290 -local destructured = {} -- ./compiler/lua54.can:291 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 -end -- ./compiler/lua54.can:293 -return r -- ./compiler/lua54.can:295 -elseif # t == 4 then -- ./compiler/lua54.can:296 -if t[3] == "=" then -- ./compiler/lua54.can:297 -local r = "" -- ./compiler/lua54.can:298 -if # vars > 0 then -- ./compiler/lua54.can:299 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 -t[2], -- ./compiler/lua54.can:300 -vars[1], -- ./compiler/lua54.can:300 -{ -- ./compiler/lua54.can:300 -["tag"] = "Paren", -- ./compiler/lua54.can:300 -values[1] -- ./compiler/lua54.can:300 -} -- ./compiler/lua54.can:300 -}, "Op")) -- ./compiler/lua54.can:300 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 +end -- ./compiler/lua54.can:233 +else -- ./compiler/lua54.can:233 +return "" -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +tags = setmetatable({ -- ./compiler/lua54.can:241 +["Block"] = function(t) -- ./compiler/lua54.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 +hasPush = false -- ./compiler/lua54.can:247 +end -- ./compiler/lua54.can:247 +local r = push("scope", {}) -- ./compiler/lua54.can:249 +if hasPush then -- ./compiler/lua54.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 +end -- ./compiler/lua54.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 +end -- ./compiler/lua54.can:254 +if t[# t] then -- ./compiler/lua54.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 +end -- ./compiler/lua54.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 +end -- ./compiler/lua54.can:260 +return r .. pop("scope") -- ./compiler/lua54.can:262 +end, -- ./compiler/lua54.can:262 +["Do"] = function(t) -- ./compiler/lua54.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 +end, -- ./compiler/lua54.can:269 +["Set"] = function(t) -- ./compiler/lua54.can:272 +local expr = t[# t] -- ./compiler/lua54.can:274 +local vars, values = {}, {} -- ./compiler/lua54.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 +else -- ./compiler/lua54.can:280 +table["insert"](vars, n) -- ./compiler/lua54.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 +local r = "" -- ./compiler/lua54.can:288 +if # vars > 0 then -- ./compiler/lua54.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 +end -- ./compiler/lua54.can:290 +if # destructuringVars > 0 then -- ./compiler/lua54.can:292 +local destructured = {} -- ./compiler/lua54.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 +end -- ./compiler/lua54.can:295 +return r -- ./compiler/lua54.can:297 +elseif # t == 4 then -- ./compiler/lua54.can:298 +if t[3] == "=" then -- ./compiler/lua54.can:299 +local r = "" -- ./compiler/lua54.can:300 +if # vars > 0 then -- ./compiler/lua54.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 t[2], -- ./compiler/lua54.can:302 -vars[i], -- ./compiler/lua54.can:302 +vars[1], -- ./compiler/lua54.can:302 { -- ./compiler/lua54.can:302 ["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[i] -- ./compiler/lua54.can:302 +values[1] -- ./compiler/lua54.can:302 } -- ./compiler/lua54.can:302 }, "Op")) -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -if # destructuringVars > 0 then -- ./compiler/lua54.can:305 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 -end -- ./compiler/lua54.can:308 -return r -- ./compiler/lua54.can:310 -else -- ./compiler/lua54.can:310 -local r = "" -- ./compiler/lua54.can:312 -if # vars > 0 then -- ./compiler/lua54.can:313 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 -t[3], -- ./compiler/lua54.can:314 -{ -- ./compiler/lua54.can:314 -["tag"] = "Paren", -- ./compiler/lua54.can:314 -values[1] -- ./compiler/lua54.can:314 -}, -- ./compiler/lua54.can:314 -vars[1] -- ./compiler/lua54.can:314 -}, "Op")) -- ./compiler/lua54.can:314 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 +t[2], -- ./compiler/lua54.can:304 +vars[i], -- ./compiler/lua54.can:304 +{ -- ./compiler/lua54.can:304 +["tag"] = "Paren", -- ./compiler/lua54.can:304 +values[i] -- ./compiler/lua54.can:304 +} -- ./compiler/lua54.can:304 +}, "Op")) -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +if # destructuringVars > 0 then -- ./compiler/lua54.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +return r -- ./compiler/lua54.can:312 +else -- ./compiler/lua54.can:312 +local r = "" -- ./compiler/lua54.can:314 +if # vars > 0 then -- ./compiler/lua54.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 t[3], -- ./compiler/lua54.can:316 { -- ./compiler/lua54.can:316 ["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[i] -- ./compiler/lua54.can:316 +values[1] -- ./compiler/lua54.can:316 }, -- ./compiler/lua54.can:316 -vars[i] -- ./compiler/lua54.can:316 +vars[1] -- ./compiler/lua54.can:316 }, "Op")) -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -if # destructuringVars > 0 then -- ./compiler/lua54.can:319 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 -end -- ./compiler/lua54.can:322 -return r -- ./compiler/lua54.can:324 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 +t[3], -- ./compiler/lua54.can:318 +{ -- ./compiler/lua54.can:318 +["tag"] = "Paren", -- ./compiler/lua54.can:318 +values[i] -- ./compiler/lua54.can:318 +}, -- ./compiler/lua54.can:318 +vars[i] -- ./compiler/lua54.can:318 +}, "Op")) -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +if # destructuringVars > 0 then -- ./compiler/lua54.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 end -- ./compiler/lua54.can:324 -else -- ./compiler/lua54.can:324 -local r = "" -- ./compiler/lua54.can:327 -if # vars > 0 then -- ./compiler/lua54.can:328 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 -t[2], -- ./compiler/lua54.can:329 -vars[1], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Op", -- ./compiler/lua54.can:329 -t[4], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Paren", -- ./compiler/lua54.can:329 -values[1] -- ./compiler/lua54.can:329 -}, -- ./compiler/lua54.can:329 -vars[1] -- ./compiler/lua54.can:329 -} -- ./compiler/lua54.can:329 -}, "Op")) -- ./compiler/lua54.can:329 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:326 +end -- ./compiler/lua54.can:326 +else -- ./compiler/lua54.can:326 +local r = "" -- ./compiler/lua54.can:329 +if # vars > 0 then -- ./compiler/lua54.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 t[2], -- ./compiler/lua54.can:331 -vars[i], -- ./compiler/lua54.can:331 +vars[1], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Op", -- ./compiler/lua54.can:331 t[4], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[i] -- ./compiler/lua54.can:331 +values[1] -- ./compiler/lua54.can:331 }, -- ./compiler/lua54.can:331 -vars[i] -- ./compiler/lua54.can:331 +vars[1] -- ./compiler/lua54.can:331 } -- ./compiler/lua54.can:331 }, "Op")) -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -if # destructuringVars > 0 then -- ./compiler/lua54.can:334 -local destructured = { -- ./compiler/lua54.can:335 -["rightOp"] = t[2], -- ./compiler/lua54.can:335 -["leftOp"] = t[4] -- ./compiler/lua54.can:335 -} -- ./compiler/lua54.can:335 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 -end -- ./compiler/lua54.can:337 -return r -- ./compiler/lua54.can:339 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 +t[2], -- ./compiler/lua54.can:333 +vars[i], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Op", -- ./compiler/lua54.can:333 +t[4], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Paren", -- ./compiler/lua54.can:333 +values[i] -- ./compiler/lua54.can:333 +}, -- ./compiler/lua54.can:333 +vars[i] -- ./compiler/lua54.can:333 +} -- ./compiler/lua54.can:333 +}, "Op")) -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +if # destructuringVars > 0 then -- ./compiler/lua54.can:336 +local destructured = { -- ./compiler/lua54.can:337 +["rightOp"] = t[2], -- ./compiler/lua54.can:337 +["leftOp"] = t[4] -- ./compiler/lua54.can:337 +} -- ./compiler/lua54.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 end -- ./compiler/lua54.can:339 -end, -- ./compiler/lua54.can:339 -["While"] = function(t) -- ./compiler/lua54.can:343 -local r = "" -- ./compiler/lua54.can:344 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 -if # lets > 0 then -- ./compiler/lua54.can:347 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 -if # lets > 0 then -- ./compiler/lua54.can:354 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 -end -- ./compiler/lua54.can:355 -if hasContinue then -- ./compiler/lua54.can:357 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 -end -- ./compiler/lua54.can:358 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 -if hasContinue then -- ./compiler/lua54.can:361 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 -end -- ./compiler/lua54.can:362 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 -if # lets > 0 then -- ./compiler/lua54.can:365 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 -end -- ./compiler/lua54.can:367 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:341 +end -- ./compiler/lua54.can:341 +end, -- ./compiler/lua54.can:341 +["While"] = function(t) -- ./compiler/lua54.can:345 +local r = "" -- ./compiler/lua54.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 +if # lets > 0 then -- ./compiler/lua54.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 +if # lets > 0 then -- ./compiler/lua54.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 +end -- ./compiler/lua54.can:357 +if hasContinue then -- ./compiler/lua54.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 +end -- ./compiler/lua54.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 +if hasContinue then -- ./compiler/lua54.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 +end -- ./compiler/lua54.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 +if # lets > 0 then -- ./compiler/lua54.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 end -- ./compiler/lua54.can:369 -return r -- ./compiler/lua54.can:371 -end, -- ./compiler/lua54.can:371 -["Repeat"] = function(t) -- ./compiler/lua54.can:374 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 -local r = "repeat" .. indent() -- ./compiler/lua54.can:376 -if hasContinue then -- ./compiler/lua54.can:377 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 -end -- ./compiler/lua54.can:378 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 -if hasContinue then -- ./compiler/lua54.can:381 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 -end -- ./compiler/lua54.can:382 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 -return r -- ./compiler/lua54.can:385 -end, -- ./compiler/lua54.can:385 -["If"] = function(t) -- ./compiler/lua54.can:388 -local r = "" -- ./compiler/lua54.can:389 -local toClose = 0 -- ./compiler/lua54.can:390 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 -if # lets > 0 then -- ./compiler/lua54.can:392 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 -toClose = toClose + (1) -- ./compiler/lua54.can:394 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 -if # lets > 0 then -- ./compiler/lua54.can:402 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 -toClose = toClose + (1) -- ./compiler/lua54.can:404 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 -end -- ./compiler/lua54.can:406 -else -- ./compiler/lua54.can:406 -r = r .. ("else") -- ./compiler/lua54.can:409 -end -- ./compiler/lua54.can:409 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 +end -- ./compiler/lua54.can:371 +return r -- ./compiler/lua54.can:373 +end, -- ./compiler/lua54.can:373 +["Repeat"] = function(t) -- ./compiler/lua54.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 +local r = "repeat" .. indent() -- ./compiler/lua54.can:378 +if hasContinue then -- ./compiler/lua54.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 +end -- ./compiler/lua54.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 +if hasContinue then -- ./compiler/lua54.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 +end -- ./compiler/lua54.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 +return r -- ./compiler/lua54.can:387 +end, -- ./compiler/lua54.can:387 +["If"] = function(t) -- ./compiler/lua54.can:390 +local r = "" -- ./compiler/lua54.can:391 +local toClose = 0 -- ./compiler/lua54.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 +if # lets > 0 then -- ./compiler/lua54.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 +toClose = toClose + (1) -- ./compiler/lua54.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 +if # lets > 0 then -- ./compiler/lua54.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 +toClose = toClose + (1) -- ./compiler/lua54.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +else -- ./compiler/lua54.can:408 +r = r .. ("else") -- ./compiler/lua54.can:411 end -- ./compiler/lua54.can:411 -if # t % 2 == 1 then -- ./compiler/lua54.can:413 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 -end -- ./compiler/lua54.can:414 -r = r .. ("end") -- ./compiler/lua54.can:416 -for i = 1, toClose do -- ./compiler/lua54.can:417 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 -end -- ./compiler/lua54.can:418 -return r -- ./compiler/lua54.can:420 -end, -- ./compiler/lua54.can:420 -["Fornum"] = function(t) -- ./compiler/lua54.can:423 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 -if # t == 5 then -- ./compiler/lua54.can:425 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 -if hasContinue then -- ./compiler/lua54.can:428 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 -end -- ./compiler/lua54.can:429 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 -if hasContinue then -- ./compiler/lua54.can:432 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 -end -- ./compiler/lua54.can:433 -return r .. unindent() .. "end" -- ./compiler/lua54.can:435 -else -- ./compiler/lua54.can:435 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 -if hasContinue then -- ./compiler/lua54.can:439 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 -end -- ./compiler/lua54.can:440 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 -if hasContinue then -- ./compiler/lua54.can:443 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 -end -- ./compiler/lua54.can:444 -return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 +end -- ./compiler/lua54.can:413 +if # t % 2 == 1 then -- ./compiler/lua54.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 +end -- ./compiler/lua54.can:416 +r = r .. ("end") -- ./compiler/lua54.can:418 +for i = 1, toClose do -- ./compiler/lua54.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 +end -- ./compiler/lua54.can:420 +return r -- ./compiler/lua54.can:422 +end, -- ./compiler/lua54.can:422 +["Fornum"] = function(t) -- ./compiler/lua54.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 +if # t == 5 then -- ./compiler/lua54.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 +if hasContinue then -- ./compiler/lua54.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 +end -- ./compiler/lua54.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 +if hasContinue then -- ./compiler/lua54.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 +end -- ./compiler/lua54.can:435 +return r .. unindent() .. "end" -- ./compiler/lua54.can:437 +else -- ./compiler/lua54.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 +if hasContinue then -- ./compiler/lua54.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 +end -- ./compiler/lua54.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 +if hasContinue then -- ./compiler/lua54.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 end -- ./compiler/lua54.can:446 -end, -- ./compiler/lua54.can:446 -["Forin"] = function(t) -- ./compiler/lua54.can:450 -local destructured = {} -- ./compiler/lua54.can:451 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 -if hasContinue then -- ./compiler/lua54.can:454 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 -end -- ./compiler/lua54.can:455 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 -if hasContinue then -- ./compiler/lua54.can:458 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 -end -- ./compiler/lua54.can:459 -return r .. unindent() .. "end" -- ./compiler/lua54.can:461 -end, -- ./compiler/lua54.can:461 -["Local"] = function(t) -- ./compiler/lua54.can:464 -local destructured = {} -- ./compiler/lua54.can:465 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 -if t[2][1] then -- ./compiler/lua54.can:467 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 -end -- ./compiler/lua54.can:468 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 -end, -- ./compiler/lua54.can:470 -["Let"] = function(t) -- ./compiler/lua54.can:473 -local destructured = {} -- ./compiler/lua54.can:474 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 -local r = "local " .. nameList -- ./compiler/lua54.can:476 -if t[2][1] then -- ./compiler/lua54.can:477 -if all(t[2], { -- ./compiler/lua54.can:478 -"Nil", -- ./compiler/lua54.can:478 -"Dots", -- ./compiler/lua54.can:478 -"Boolean", -- ./compiler/lua54.can:478 -"Number", -- ./compiler/lua54.can:478 -"String" -- ./compiler/lua54.can:478 -}) then -- ./compiler/lua54.can:478 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 -else -- ./compiler/lua54.can:479 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 -end, -- ./compiler/lua54.can:484 -["Localrec"] = function(t) -- ./compiler/lua54.can:487 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 -end, -- ./compiler/lua54.can:488 -["Goto"] = function(t) -- ./compiler/lua54.can:491 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 -end, -- ./compiler/lua54.can:492 -["Label"] = function(t) -- ./compiler/lua54.can:495 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 -end, -- ./compiler/lua54.can:496 -["Return"] = function(t) -- ./compiler/lua54.can:499 -local push = peek("push") -- ./compiler/lua54.can:500 -if push then -- ./compiler/lua54.can:501 -local r = "" -- ./compiler/lua54.can:502 -for _, val in ipairs(t) do -- ./compiler/lua54.can:503 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 -end -- ./compiler/lua54.can:504 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 -else -- ./compiler/lua54.can:506 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 -end -- ./compiler/lua54.can:508 -end, -- ./compiler/lua54.can:508 -["Push"] = function(t) -- ./compiler/lua54.can:512 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 -r = "" -- ./compiler/lua54.can:514 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -if t[# t] then -- ./compiler/lua54.can:518 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 -else -- ./compiler/lua54.can:520 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -return r -- ./compiler/lua54.can:525 -end, -- ./compiler/lua54.can:525 -["Break"] = function() -- ./compiler/lua54.can:528 -return "break" -- ./compiler/lua54.can:529 -end, -- ./compiler/lua54.can:529 -["Continue"] = function() -- ./compiler/lua54.can:532 -return "goto " .. var("continue") -- ./compiler/lua54.can:533 -end, -- ./compiler/lua54.can:533 -["Nil"] = function() -- ./compiler/lua54.can:540 -return "nil" -- ./compiler/lua54.can:541 -end, -- ./compiler/lua54.can:541 -["Dots"] = function() -- ./compiler/lua54.can:544 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 -return r -- ./compiler/lua54.can:550 -else -- ./compiler/lua54.can:550 -return "..." -- ./compiler/lua54.can:552 -end -- ./compiler/lua54.can:552 -end, -- ./compiler/lua54.can:552 -["Boolean"] = function(t) -- ./compiler/lua54.can:556 -return tostring(t[1]) -- ./compiler/lua54.can:557 -end, -- ./compiler/lua54.can:557 -["Number"] = function(t) -- ./compiler/lua54.can:560 -return tostring(t[1]) -- ./compiler/lua54.can:561 -end, -- ./compiler/lua54.can:561 -["String"] = function(t) -- ./compiler/lua54.can:564 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 -end, -- ./compiler/lua54.can:565 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 -local r = "(" -- ./compiler/lua54.can:569 -local decl = {} -- ./compiler/lua54.can:570 -if t[1][1] then -- ./compiler/lua54.can:571 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 -r = r .. (id) -- ./compiler/lua54.can:577 -else -- ./compiler/lua54.can:577 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 -end -- ./compiler/lua54.can:579 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 -r = r .. (", " .. id) -- ./compiler/lua54.can:587 -else -- ./compiler/lua54.can:587 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 -r = r .. (d .. newline()) -- ./compiler/lua54.can:595 -end -- ./compiler/lua54.can:595 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 -end -- ./compiler/lua54.can:598 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 -if hasPush then -- ./compiler/lua54.can:601 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 -else -- ./compiler/lua54.can:602 -push("push", false) -- ./compiler/lua54.can:604 -end -- ./compiler/lua54.can:604 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 -end -- ./compiler/lua54.can:608 -pop("push") -- ./compiler/lua54.can:610 -return r .. unindent() .. "end" -- ./compiler/lua54.can:611 -end, -- ./compiler/lua54.can:611 -["Function"] = function(t) -- ./compiler/lua54.can:613 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 -end, -- ./compiler/lua54.can:614 -["Pair"] = function(t) -- ./compiler/lua54.can:617 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 -end, -- ./compiler/lua54.can:618 -["Table"] = function(t) -- ./compiler/lua54.can:620 -if # t == 0 then -- ./compiler/lua54.can:621 -return "{}" -- ./compiler/lua54.can:622 -elseif # t == 1 then -- ./compiler/lua54.can:623 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 -else -- ./compiler/lua54.can:624 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 -end -- ./compiler/lua54.can:626 -end, -- ./compiler/lua54.can:626 -["TableCompr"] = function(t) -- ./compiler/lua54.can:630 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 -end, -- ./compiler/lua54.can:631 -["Op"] = function(t) -- ./compiler/lua54.can:634 -local r -- ./compiler/lua54.can:635 -if # t == 2 then -- ./compiler/lua54.can:636 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 -else -- ./compiler/lua54.can:638 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 -end -- ./compiler/lua54.can:640 +return r .. unindent() .. "end" -- ./compiler/lua54.can:448 +end -- ./compiler/lua54.can:448 +end, -- ./compiler/lua54.can:448 +["Forin"] = function(t) -- ./compiler/lua54.can:452 +local destructured = {} -- ./compiler/lua54.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 +if hasContinue then -- ./compiler/lua54.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 +end -- ./compiler/lua54.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 +if hasContinue then -- ./compiler/lua54.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 +end -- ./compiler/lua54.can:461 +return r .. unindent() .. "end" -- ./compiler/lua54.can:463 +end, -- ./compiler/lua54.can:463 +["Local"] = function(t) -- ./compiler/lua54.can:466 +local destructured = {} -- ./compiler/lua54.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 +if t[2][1] then -- ./compiler/lua54.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 +end -- ./compiler/lua54.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 +end, -- ./compiler/lua54.can:472 +["Let"] = function(t) -- ./compiler/lua54.can:475 +local destructured = {} -- ./compiler/lua54.can:476 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 +local r = "local " .. nameList -- ./compiler/lua54.can:478 +if t[2][1] then -- ./compiler/lua54.can:479 +if all(t[2], { -- ./compiler/lua54.can:480 +"Nil", -- ./compiler/lua54.can:480 +"Dots", -- ./compiler/lua54.can:480 +"Boolean", -- ./compiler/lua54.can:480 +"Number", -- ./compiler/lua54.can:480 +"String" -- ./compiler/lua54.can:480 +}) then -- ./compiler/lua54.can:480 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +else -- ./compiler/lua54.can:481 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Localrec"] = function(t) -- ./compiler/lua54.can:489 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Goto"] = function(t) -- ./compiler/lua54.can:493 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 +end, -- ./compiler/lua54.can:494 +["Label"] = function(t) -- ./compiler/lua54.can:497 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 +end, -- ./compiler/lua54.can:498 +["Return"] = function(t) -- ./compiler/lua54.can:501 +local push = peek("push") -- ./compiler/lua54.can:502 +if push then -- ./compiler/lua54.can:503 +local r = "" -- ./compiler/lua54.can:504 +for _, val in ipairs(t) do -- ./compiler/lua54.can:505 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 +end -- ./compiler/lua54.can:506 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 +else -- ./compiler/lua54.can:508 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +end, -- ./compiler/lua54.can:510 +["Push"] = function(t) -- ./compiler/lua54.can:514 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 +r = "" -- ./compiler/lua54.can:516 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 +end -- ./compiler/lua54.can:518 +if t[# t] then -- ./compiler/lua54.can:520 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 +else -- ./compiler/lua54.can:522 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +return r -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Break"] = function() -- ./compiler/lua54.can:530 +return "break" -- ./compiler/lua54.can:531 +end, -- ./compiler/lua54.can:531 +["Continue"] = function() -- ./compiler/lua54.can:534 +return "goto " .. var("continue") -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Nil"] = function() -- ./compiler/lua54.can:542 +return "nil" -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Dots"] = function() -- ./compiler/lua54.can:546 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 +return r -- ./compiler/lua54.can:552 +else -- ./compiler/lua54.can:552 +return "..." -- ./compiler/lua54.can:554 +end -- ./compiler/lua54.can:554 +end, -- ./compiler/lua54.can:554 +["Boolean"] = function(t) -- ./compiler/lua54.can:558 +return tostring(t[1]) -- ./compiler/lua54.can:559 +end, -- ./compiler/lua54.can:559 +["Number"] = function(t) -- ./compiler/lua54.can:562 +return tostring(t[1]) -- ./compiler/lua54.can:563 +end, -- ./compiler/lua54.can:563 +["String"] = function(t) -- ./compiler/lua54.can:566 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 +end, -- ./compiler/lua54.can:567 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 +local r = "(" -- ./compiler/lua54.can:571 +local decl = {} -- ./compiler/lua54.can:572 +if t[1][1] then -- ./compiler/lua54.can:573 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 +r = r .. (id) -- ./compiler/lua54.can:579 +else -- ./compiler/lua54.can:579 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 +r = r .. (", " .. id) -- ./compiler/lua54.can:589 +else -- ./compiler/lua54.can:589 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 +r = r .. (d .. newline()) -- ./compiler/lua54.can:597 +end -- ./compiler/lua54.can:597 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 +end -- ./compiler/lua54.can:600 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 +if hasPush then -- ./compiler/lua54.can:603 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 +else -- ./compiler/lua54.can:604 +push("push", false) -- ./compiler/lua54.can:606 +end -- ./compiler/lua54.can:606 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 +end -- ./compiler/lua54.can:610 +pop("push") -- ./compiler/lua54.can:612 +return r .. unindent() .. "end" -- ./compiler/lua54.can:613 +end, -- ./compiler/lua54.can:613 +["Function"] = function(t) -- ./compiler/lua54.can:615 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 +end, -- ./compiler/lua54.can:616 +["Pair"] = function(t) -- ./compiler/lua54.can:619 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 +end, -- ./compiler/lua54.can:620 +["Table"] = function(t) -- ./compiler/lua54.can:622 +if # t == 0 then -- ./compiler/lua54.can:623 +return "{}" -- ./compiler/lua54.can:624 +elseif # t == 1 then -- ./compiler/lua54.can:625 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 +end -- ./compiler/lua54.can:628 +end, -- ./compiler/lua54.can:628 +["TableCompr"] = function(t) -- ./compiler/lua54.can:632 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 +end, -- ./compiler/lua54.can:633 +["Op"] = function(t) -- ./compiler/lua54.can:636 +local r -- ./compiler/lua54.can:637 +if # t == 2 then -- ./compiler/lua54.can:638 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 else -- ./compiler/lua54.can:640 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 -else -- ./compiler/lua54.can:644 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -return r -- ./compiler/lua54.can:649 -end, -- ./compiler/lua54.can:649 -["Paren"] = function(t) -- ./compiler/lua54.can:652 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 -end, -- ./compiler/lua54.can:653 -["MethodStub"] = function(t) -- ./compiler/lua54.can:656 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 -end, -- ./compiler/lua54.can:662 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 -end, -- ./compiler/lua54.can:672 -["LetExpr"] = function(t) -- ./compiler/lua54.can:679 -return lua(t[1][1]) -- ./compiler/lua54.can:680 -end, -- ./compiler/lua54.can:680 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 -local r = "(function()" .. indent() -- ./compiler/lua54.can:686 -if hasPush then -- ./compiler/lua54.can:687 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 -else -- ./compiler/lua54.can:688 -push("push", false) -- ./compiler/lua54.can:690 -end -- ./compiler/lua54.can:690 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 -if hasPush then -- ./compiler/lua54.can:693 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 -end -- ./compiler/lua54.can:694 -pop("push") -- ./compiler/lua54.can:696 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 -return r -- ./compiler/lua54.can:698 -end, -- ./compiler/lua54.can:698 -["DoExpr"] = function(t) -- ./compiler/lua54.can:701 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 -end -- ./compiler/lua54.can:703 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 -end, -- ./compiler/lua54.can:705 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 -end, -- ./compiler/lua54.can:709 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 -end, -- ./compiler/lua54.can:713 -["IfExpr"] = function(t) -- ./compiler/lua54.can:716 -for i = 2, # t do -- ./compiler/lua54.can:717 -local block = t[i] -- ./compiler/lua54.can:718 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 -end, -- ./compiler/lua54.can:723 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 -end, -- ./compiler/lua54.can:727 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 -end, -- ./compiler/lua54.can:731 -["Call"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 -local replacement = macro["replacement"] -- ./compiler/lua54.can:742 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 -macroargs["..."] = (function() -- ./compiler/lua54.can:746 -local self = {} -- ./compiler/lua54.can:746 -for j = i + 1, # t do -- ./compiler/lua54.can:746 -self[#self+1] = t[j] -- ./compiler/lua54.can:746 -end -- ./compiler/lua54.can:746 -return self -- ./compiler/lua54.can:746 -end)() -- ./compiler/lua54.can:746 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 -if t[i + 1] == nil then -- ./compiler/lua54.can:748 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 -end -- ./compiler/lua54.can:749 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 -else -- ./compiler/lua54.can:751 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -push("macroargs", macroargs) -- ./compiler/lua54.can:756 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 -local r = lua(replacement) -- ./compiler/lua54.can:758 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 -pop("macroargs") -- ./compiler/lua54.can:760 -return r -- ./compiler/lua54.can:761 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 -else -- ./compiler/lua54.can:764 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 -end -- ./compiler/lua54.can:766 -else -- ./compiler/lua54.can:766 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 +end -- ./compiler/lua54.can:642 +else -- ./compiler/lua54.can:642 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 +else -- ./compiler/lua54.can:646 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +return r -- ./compiler/lua54.can:651 +end, -- ./compiler/lua54.can:651 +["Paren"] = function(t) -- ./compiler/lua54.can:654 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 +end, -- ./compiler/lua54.can:655 +["MethodStub"] = function(t) -- ./compiler/lua54.can:658 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 +end, -- ./compiler/lua54.can:664 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 +end, -- ./compiler/lua54.can:674 +["LetExpr"] = function(t) -- ./compiler/lua54.can:681 +return lua(t[1][1]) -- ./compiler/lua54.can:682 +end, -- ./compiler/lua54.can:682 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 +local r = "(function()" .. indent() -- ./compiler/lua54.can:688 +if hasPush then -- ./compiler/lua54.can:689 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 +else -- ./compiler/lua54.can:690 +push("push", false) -- ./compiler/lua54.can:692 +end -- ./compiler/lua54.can:692 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 +if hasPush then -- ./compiler/lua54.can:695 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 +end -- ./compiler/lua54.can:696 +pop("push") -- ./compiler/lua54.can:698 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 +return r -- ./compiler/lua54.can:700 +end, -- ./compiler/lua54.can:700 +["DoExpr"] = function(t) -- ./compiler/lua54.can:703 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 +end -- ./compiler/lua54.can:705 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 +end, -- ./compiler/lua54.can:707 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 +end, -- ./compiler/lua54.can:711 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 +end, -- ./compiler/lua54.can:715 +["IfExpr"] = function(t) -- ./compiler/lua54.can:718 +for i = 2, # t do -- ./compiler/lua54.can:719 +local block = t[i] -- ./compiler/lua54.can:720 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 +end, -- ./compiler/lua54.can:725 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 +end, -- ./compiler/lua54.can:729 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["Call"] = function(t) -- ./compiler/lua54.can:739 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 +local replacement = macro["replacement"] -- ./compiler/lua54.can:744 +local r -- ./compiler/lua54.can:745 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 +if type(replacement) == "function" then -- ./compiler/lua54.can:747 +local args = {} -- ./compiler/lua54.can:748 +for i = 2, # t do -- ./compiler/lua54.can:749 +table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 +end -- ./compiler/lua54.can:750 +r = replacement(unpack(args)) -- ./compiler/lua54.can:752 +else -- ./compiler/lua54.can:752 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 +macroargs["..."] = (function() -- ./compiler/lua54.can:757 +local self = {} -- ./compiler/lua54.can:757 +for j = i + 1, # t do -- ./compiler/lua54.can:757 +self[#self+1] = t[j] -- ./compiler/lua54.can:757 +end -- ./compiler/lua54.can:757 +return self -- ./compiler/lua54.can:757 +end)() -- ./compiler/lua54.can:757 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 +if t[i + 1] == nil then -- ./compiler/lua54.can:759 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 +end -- ./compiler/lua54.can:760 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 +else -- ./compiler/lua54.can:762 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +push("macroargs", macroargs) -- ./compiler/lua54.can:767 +r = lua(replacement) -- ./compiler/lua54.can:768 +pop("macroargs") -- ./compiler/lua54.can:769 end -- ./compiler/lua54.can:769 -end, -- ./compiler/lua54.can:769 -["SafeCall"] = function(t) -- ./compiler/lua54.can:773 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 +return r -- ./compiler/lua54.can:772 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 else -- ./compiler/lua54.can:775 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 end -- ./compiler/lua54.can:777 -end, -- ./compiler/lua54.can:777 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 -if start == nil then start = 1 end -- ./compiler/lua54.can:782 -local r -- ./compiler/lua54.can:783 -if t[start] then -- ./compiler/lua54.can:784 -r = lua(t[start]) -- ./compiler/lua54.can:785 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 -end -- ./compiler/lua54.can:787 -else -- ./compiler/lua54.can:787 -r = "" -- ./compiler/lua54.can:790 -end -- ./compiler/lua54.can:790 -return r -- ./compiler/lua54.can:792 -end, -- ./compiler/lua54.can:792 -["Id"] = function(t) -- ./compiler/lua54.can:795 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 -local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:802 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 -local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 -return r -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -return t[1] -- ./compiler/lua54.can:810 -end, -- ./compiler/lua54.can:810 -["AttributeId"] = function(t) -- ./compiler/lua54.can:813 -if t[2] then -- ./compiler/lua54.can:814 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 -else -- ./compiler/lua54.can:815 -return t[1] -- ./compiler/lua54.can:817 -end -- ./compiler/lua54.can:817 -end, -- ./compiler/lua54.can:817 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 -if t["id"] then -- ./compiler/lua54.can:822 -return t["id"] -- ./compiler/lua54.can:823 -else -- ./compiler/lua54.can:823 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 -for j = 1, # t, 1 do -- ./compiler/lua54.can:827 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 -end -- ./compiler/lua54.can:828 -table["insert"](d, vars) -- ./compiler/lua54.can:830 -t["id"] = vars["id"] -- ./compiler/lua54.can:831 -return vars["id"] -- ./compiler/lua54.can:832 -end -- ./compiler/lua54.can:832 -end, -- ./compiler/lua54.can:832 -["Index"] = function(t) -- ./compiler/lua54.can:836 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 -else -- ./compiler/lua54.can:838 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 -end -- ./compiler/lua54.can:840 -end, -- ./compiler/lua54.can:840 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 -local l = {} -- ./compiler/lua54.can:846 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 -table["insert"](l, 1, t) -- ./compiler/lua54.can:848 -t = t[1] -- ./compiler/lua54.can:849 -end -- ./compiler/lua54.can:849 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 -for _, e in ipairs(l) do -- ./compiler/lua54.can:852 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 -else -- ./compiler/lua54.can:855 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 -return r -- ./compiler/lua54.can:861 -else -- ./compiler/lua54.can:861 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 -end -- ./compiler/lua54.can:863 -end, -- ./compiler/lua54.can:863 -["_opid"] = { -- ./compiler/lua54.can:868 -["add"] = "+", -- ./compiler/lua54.can:869 -["sub"] = "-", -- ./compiler/lua54.can:869 -["mul"] = "*", -- ./compiler/lua54.can:869 -["div"] = "/", -- ./compiler/lua54.can:869 -["idiv"] = "//", -- ./compiler/lua54.can:870 -["mod"] = "%", -- ./compiler/lua54.can:870 -["pow"] = "^", -- ./compiler/lua54.can:870 -["concat"] = "..", -- ./compiler/lua54.can:870 -["band"] = "&", -- ./compiler/lua54.can:871 -["bor"] = "|", -- ./compiler/lua54.can:871 -["bxor"] = "~", -- ./compiler/lua54.can:871 -["shl"] = "<<", -- ./compiler/lua54.can:871 -["shr"] = ">>", -- ./compiler/lua54.can:871 -["eq"] = "==", -- ./compiler/lua54.can:872 -["ne"] = "~=", -- ./compiler/lua54.can:872 -["lt"] = "<", -- ./compiler/lua54.can:872 -["gt"] = ">", -- ./compiler/lua54.can:872 -["le"] = "<=", -- ./compiler/lua54.can:872 -["ge"] = ">=", -- ./compiler/lua54.can:872 -["and"] = "and", -- ./compiler/lua54.can:873 -["or"] = "or", -- ./compiler/lua54.can:873 -["unm"] = "-", -- ./compiler/lua54.can:873 -["len"] = "#", -- ./compiler/lua54.can:873 -["bnot"] = "~", -- ./compiler/lua54.can:873 -["not"] = "not" -- ./compiler/lua54.can:873 -} -- ./compiler/lua54.can:873 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 -end }) -- ./compiler/lua54.can:877 +else -- ./compiler/lua54.can:777 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 +end -- ./compiler/lua54.can:780 +end, -- ./compiler/lua54.can:780 +["SafeCall"] = function(t) -- ./compiler/lua54.can:784 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 +else -- ./compiler/lua54.can:786 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 +end -- ./compiler/lua54.can:788 +end, -- ./compiler/lua54.can:788 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 +if start == nil then start = 1 end -- ./compiler/lua54.can:793 +local r -- ./compiler/lua54.can:794 +if t[start] then -- ./compiler/lua54.can:795 +r = lua(t[start]) -- ./compiler/lua54.can:796 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 +end -- ./compiler/lua54.can:798 +else -- ./compiler/lua54.can:798 +r = "" -- ./compiler/lua54.can:801 +end -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:803 +end, -- ./compiler/lua54.can:803 +["Id"] = function(t) -- ./compiler/lua54.can:806 +local r = t[1] -- ./compiler/lua54.can:807 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 +r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 +local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 +if type(macro) == "function" then -- ./compiler/lua54.can:815 +r = macro() -- ./compiler/lua54.can:816 +else -- ./compiler/lua54.can:816 +r = lua(macro) -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 +end -- ./compiler/lua54.can:821 +return r -- ./compiler/lua54.can:823 +end, -- ./compiler/lua54.can:823 +["AttributeId"] = function(t) -- ./compiler/lua54.can:826 +if t[2] then -- ./compiler/lua54.can:827 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 +else -- ./compiler/lua54.can:828 +return t[1] -- ./compiler/lua54.can:830 +end -- ./compiler/lua54.can:830 +end, -- ./compiler/lua54.can:830 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 +if t["id"] then -- ./compiler/lua54.can:835 +return t["id"] -- ./compiler/lua54.can:836 +else -- ./compiler/lua54.can:836 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 +for j = 1, # t, 1 do -- ./compiler/lua54.can:840 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 +end -- ./compiler/lua54.can:841 +table["insert"](d, vars) -- ./compiler/lua54.can:843 +t["id"] = vars["id"] -- ./compiler/lua54.can:844 +return vars["id"] -- ./compiler/lua54.can:845 +end -- ./compiler/lua54.can:845 +end, -- ./compiler/lua54.can:845 +["Index"] = function(t) -- ./compiler/lua54.can:849 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 +else -- ./compiler/lua54.can:851 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 +end -- ./compiler/lua54.can:853 +end, -- ./compiler/lua54.can:853 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 +local l = {} -- ./compiler/lua54.can:859 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 +table["insert"](l, 1, t) -- ./compiler/lua54.can:861 +t = t[1] -- ./compiler/lua54.can:862 +end -- ./compiler/lua54.can:862 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 +for _, e in ipairs(l) do -- ./compiler/lua54.can:865 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 +else -- ./compiler/lua54.can:868 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 +return r -- ./compiler/lua54.can:874 +else -- ./compiler/lua54.can:874 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 +end -- ./compiler/lua54.can:876 +end, -- ./compiler/lua54.can:876 +["_opid"] = { -- ./compiler/lua54.can:881 +["add"] = "+", -- ./compiler/lua54.can:882 +["sub"] = "-", -- ./compiler/lua54.can:882 +["mul"] = "*", -- ./compiler/lua54.can:882 +["div"] = "/", -- ./compiler/lua54.can:882 +["idiv"] = "//", -- ./compiler/lua54.can:883 +["mod"] = "%", -- ./compiler/lua54.can:883 +["pow"] = "^", -- ./compiler/lua54.can:883 +["concat"] = "..", -- ./compiler/lua54.can:883 +["band"] = "&", -- ./compiler/lua54.can:884 +["bor"] = "|", -- ./compiler/lua54.can:884 +["bxor"] = "~", -- ./compiler/lua54.can:884 +["shl"] = "<<", -- ./compiler/lua54.can:884 +["shr"] = ">>", -- ./compiler/lua54.can:884 +["eq"] = "==", -- ./compiler/lua54.can:885 +["ne"] = "~=", -- ./compiler/lua54.can:885 +["lt"] = "<", -- ./compiler/lua54.can:885 +["gt"] = ">", -- ./compiler/lua54.can:885 +["le"] = "<=", -- ./compiler/lua54.can:885 +["ge"] = ">=", -- ./compiler/lua54.can:885 +["and"] = "and", -- ./compiler/lua54.can:886 +["or"] = "or", -- ./compiler/lua54.can:886 +["unm"] = "-", -- ./compiler/lua54.can:886 +["len"] = "#", -- ./compiler/lua54.can:886 +["bnot"] = "~", -- ./compiler/lua54.can:886 +["not"] = "not" -- ./compiler/lua54.can:886 +} -- ./compiler/lua54.can:886 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 +end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -3940,11 +3988,11 @@ tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 end -- ./compiler/luajit.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 -return requireStr .. code -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -local lua54 = _() or lua54 -- ./compiler/lua54.can:889 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 +return requireStr .. code -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +local lua54 = _() or lua54 -- ./compiler/lua54.can:902 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -3962,919 +4010,931 @@ local function _() -- ./compiler/luajit.can:52 local function _() -- ./compiler/luajit.can:54 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 -return function(code, ast, options, macros) -- ./compiler/lua54.can:5 -if macros == nil then macros = { -- ./compiler/lua54.can:5 -["functions"] = {}, -- ./compiler/lua54.can:5 -["variables"] = {} -- ./compiler/lua54.can:5 -} end -- ./compiler/lua54.can:5 -local lastInputPos = 1 -- ./compiler/lua54.can:7 -local prevLinePos = 1 -- ./compiler/lua54.can:8 -local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:9 -local lastLine = 1 -- ./compiler/lua54.can:10 -local indentLevel = 0 -- ./compiler/lua54.can:13 -local function newline() -- ./compiler/lua54.can:15 -local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:16 -if options["mapLines"] then -- ./compiler/lua54.can:17 -local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:18 +local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 +return function(code, ast, options, macros) -- ./compiler/lua54.can:7 +if macros == nil then macros = { -- ./compiler/lua54.can:7 +["functions"] = {}, -- ./compiler/lua54.can:7 +["variables"] = {} -- ./compiler/lua54.can:7 +} end -- ./compiler/lua54.can:7 +local lastInputPos = 1 -- ./compiler/lua54.can:9 +local prevLinePos = 1 -- ./compiler/lua54.can:10 +local lastSource = options["chunkname"] or "nil" -- ./compiler/lua54.can:11 +local lastLine = 1 -- ./compiler/lua54.can:12 +local indentLevel = 0 -- ./compiler/lua54.can:15 +local function newline() -- ./compiler/lua54.can:17 +local r = options["newline"] .. string["rep"](options["indentation"], indentLevel) -- ./compiler/lua54.can:18 +if options["mapLines"] then -- ./compiler/lua54.can:19 +local sub = code:sub(lastInputPos) -- ./compiler/lua54.can:20 local source, line = sub:sub(1, sub:find("\ ")):match(".*%-%- (.-)%:(%d+)\ -") -- ./compiler/lua54.can:19 -if source and line then -- ./compiler/lua54.can:21 -lastSource = source -- ./compiler/lua54.can:22 -lastLine = tonumber(line) -- ./compiler/lua54.can:23 -else -- ./compiler/lua54.can:23 +") -- ./compiler/lua54.can:21 +if source and line then -- ./compiler/lua54.can:23 +lastSource = source -- ./compiler/lua54.can:24 +lastLine = tonumber(line) -- ./compiler/lua54.can:25 +else -- ./compiler/lua54.can:25 for _ in code:sub(prevLinePos, lastInputPos):gmatch("\ -") do -- ./compiler/lua54.can:25 -lastLine = lastLine + (1) -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -end -- ./compiler/lua54.can:26 -prevLinePos = lastInputPos -- ./compiler/lua54.can:30 -r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:32 -end -- ./compiler/lua54.can:32 -return r -- ./compiler/lua54.can:34 +") do -- ./compiler/lua54.can:27 +lastLine = lastLine + (1) -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +end -- ./compiler/lua54.can:28 +prevLinePos = lastInputPos -- ./compiler/lua54.can:32 +r = " -- " .. lastSource .. ":" .. lastLine .. r -- ./compiler/lua54.can:34 end -- ./compiler/lua54.can:34 -local function indent() -- ./compiler/lua54.can:37 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:38 -return newline() -- ./compiler/lua54.can:39 -end -- ./compiler/lua54.can:39 -local function unindent() -- ./compiler/lua54.can:42 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:43 -return newline() -- ./compiler/lua54.can:44 -end -- ./compiler/lua54.can:44 -local states = { -- ./compiler/lua54.can:49 -["push"] = {}, -- ./compiler/lua54.can:50 -["destructuring"] = {}, -- ./compiler/lua54.can:51 -["scope"] = {}, -- ./compiler/lua54.can:52 -["macroargs"] = {} -- ./compiler/lua54.can:53 -} -- ./compiler/lua54.can:53 -local function push(name, state) -- ./compiler/lua54.can:56 -table["insert"](states[name], state) -- ./compiler/lua54.can:57 -return "" -- ./compiler/lua54.can:58 -end -- ./compiler/lua54.can:58 -local function pop(name) -- ./compiler/lua54.can:61 -table["remove"](states[name]) -- ./compiler/lua54.can:62 -return "" -- ./compiler/lua54.can:63 -end -- ./compiler/lua54.can:63 -local function set(name, state) -- ./compiler/lua54.can:66 -states[name][# states[name]] = state -- ./compiler/lua54.can:67 -return "" -- ./compiler/lua54.can:68 -end -- ./compiler/lua54.can:68 -local function peek(name) -- ./compiler/lua54.can:71 -return states[name][# states[name]] -- ./compiler/lua54.can:72 -end -- ./compiler/lua54.can:72 -local function var(name) -- ./compiler/lua54.can:77 -return options["variablePrefix"] .. name -- ./compiler/lua54.can:78 -end -- ./compiler/lua54.can:78 -local function tmp() -- ./compiler/lua54.can:82 -local scope = peek("scope") -- ./compiler/lua54.can:83 -local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:84 -table["insert"](scope, var) -- ./compiler/lua54.can:85 -return var -- ./compiler/lua54.can:86 -end -- ./compiler/lua54.can:86 -local nomacro = { -- ./compiler/lua54.can:90 -["variables"] = {}, -- ./compiler/lua54.can:90 -["functions"] = {} -- ./compiler/lua54.can:90 -} -- ./compiler/lua54.can:90 -local required = {} -- ./compiler/lua54.can:93 -local requireStr = "" -- ./compiler/lua54.can:94 -local function addRequire(mod, name, field) -- ./compiler/lua54.can:96 -local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:97 -if not required[req] then -- ./compiler/lua54.can:98 -requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:99 -required[req] = true -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -end -- ./compiler/lua54.can:100 -local loop = { -- ./compiler/lua54.can:105 -"While", -- ./compiler/lua54.can:105 -"Repeat", -- ./compiler/lua54.can:105 -"Fornum", -- ./compiler/lua54.can:105 -"Forin", -- ./compiler/lua54.can:105 -"WhileExpr", -- ./compiler/lua54.can:105 -"RepeatExpr", -- ./compiler/lua54.can:105 -"FornumExpr", -- ./compiler/lua54.can:105 -"ForinExpr" -- ./compiler/lua54.can:105 -} -- ./compiler/lua54.can:105 -local func = { -- ./compiler/lua54.can:106 -"Function", -- ./compiler/lua54.can:106 -"TableCompr", -- ./compiler/lua54.can:106 -"DoExpr", -- ./compiler/lua54.can:106 -"WhileExpr", -- ./compiler/lua54.can:106 -"RepeatExpr", -- ./compiler/lua54.can:106 -"IfExpr", -- ./compiler/lua54.can:106 -"FornumExpr", -- ./compiler/lua54.can:106 -"ForinExpr" -- ./compiler/lua54.can:106 -} -- ./compiler/lua54.can:106 -local function any(list, tags, nofollow) -- ./compiler/lua54.can:110 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:110 -local tagsCheck = {} -- ./compiler/lua54.can:111 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:112 -tagsCheck[tag] = true -- ./compiler/lua54.can:113 -end -- ./compiler/lua54.can:113 -local nofollowCheck = {} -- ./compiler/lua54.can:115 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:116 -nofollowCheck[tag] = true -- ./compiler/lua54.can:117 -end -- ./compiler/lua54.can:117 -for _, node in ipairs(list) do -- ./compiler/lua54.can:119 -if type(node) == "table" then -- ./compiler/lua54.can:120 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:121 -return node -- ./compiler/lua54.can:122 -end -- ./compiler/lua54.can:122 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:124 -local r = any(node, tags, nofollow) -- ./compiler/lua54.can:125 -if r then -- ./compiler/lua54.can:126 -return r -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -end -- ./compiler/lua54.can:126 -return nil -- ./compiler/lua54.can:130 -end -- ./compiler/lua54.can:130 -local function search(list, tags, nofollow) -- ./compiler/lua54.can:135 -if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:135 -local tagsCheck = {} -- ./compiler/lua54.can:136 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:137 -tagsCheck[tag] = true -- ./compiler/lua54.can:138 -end -- ./compiler/lua54.can:138 -local nofollowCheck = {} -- ./compiler/lua54.can:140 -for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:141 -nofollowCheck[tag] = true -- ./compiler/lua54.can:142 -end -- ./compiler/lua54.can:142 -local found = {} -- ./compiler/lua54.can:144 -for _, node in ipairs(list) do -- ./compiler/lua54.can:145 -if type(node) == "table" then -- ./compiler/lua54.can:146 -if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:147 -for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:148 -table["insert"](found, n) -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -end -- ./compiler/lua54.can:149 -if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:152 -table["insert"](found, node) -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -end -- ./compiler/lua54.can:153 -return found -- ./compiler/lua54.can:157 -end -- ./compiler/lua54.can:157 -local function all(list, tags) -- ./compiler/lua54.can:161 -for _, node in ipairs(list) do -- ./compiler/lua54.can:162 -local ok = false -- ./compiler/lua54.can:163 -for _, tag in ipairs(tags) do -- ./compiler/lua54.can:164 -if node["tag"] == tag then -- ./compiler/lua54.can:165 -ok = true -- ./compiler/lua54.can:166 -break -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -end -- ./compiler/lua54.can:167 -if not ok then -- ./compiler/lua54.can:170 -return false -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -end -- ./compiler/lua54.can:171 -return true -- ./compiler/lua54.can:174 -end -- ./compiler/lua54.can:174 -local tags -- ./compiler/lua54.can:178 -local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:180 -if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:181 -lastInputPos = ast["pos"] -- ./compiler/lua54.can:182 -end -- ./compiler/lua54.can:182 -return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:184 +return r -- ./compiler/lua54.can:36 +end -- ./compiler/lua54.can:36 +local function indent() -- ./compiler/lua54.can:39 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:40 +return newline() -- ./compiler/lua54.can:41 +end -- ./compiler/lua54.can:41 +local function unindent() -- ./compiler/lua54.can:44 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:45 +return newline() -- ./compiler/lua54.can:46 +end -- ./compiler/lua54.can:46 +local states = { -- ./compiler/lua54.can:51 +["push"] = {}, -- ./compiler/lua54.can:52 +["destructuring"] = {}, -- ./compiler/lua54.can:53 +["scope"] = {}, -- ./compiler/lua54.can:54 +["macroargs"] = {} -- ./compiler/lua54.can:55 +} -- ./compiler/lua54.can:55 +local function push(name, state) -- ./compiler/lua54.can:58 +table["insert"](states[name], state) -- ./compiler/lua54.can:59 +return "" -- ./compiler/lua54.can:60 +end -- ./compiler/lua54.can:60 +local function pop(name) -- ./compiler/lua54.can:63 +table["remove"](states[name]) -- ./compiler/lua54.can:64 +return "" -- ./compiler/lua54.can:65 +end -- ./compiler/lua54.can:65 +local function set(name, state) -- ./compiler/lua54.can:68 +states[name][# states[name]] = state -- ./compiler/lua54.can:69 +return "" -- ./compiler/lua54.can:70 +end -- ./compiler/lua54.can:70 +local function peek(name) -- ./compiler/lua54.can:73 +return states[name][# states[name]] -- ./compiler/lua54.can:74 +end -- ./compiler/lua54.can:74 +local function var(name) -- ./compiler/lua54.can:79 +return options["variablePrefix"] .. name -- ./compiler/lua54.can:80 +end -- ./compiler/lua54.can:80 +local function tmp() -- ./compiler/lua54.can:84 +local scope = peek("scope") -- ./compiler/lua54.can:85 +local var = ("%s_%s"):format(options["variablePrefix"], # scope) -- ./compiler/lua54.can:86 +table["insert"](scope, var) -- ./compiler/lua54.can:87 +return var -- ./compiler/lua54.can:88 +end -- ./compiler/lua54.can:88 +local nomacro = { -- ./compiler/lua54.can:92 +["variables"] = {}, -- ./compiler/lua54.can:92 +["functions"] = {} -- ./compiler/lua54.can:92 +} -- ./compiler/lua54.can:92 +local required = {} -- ./compiler/lua54.can:95 +local requireStr = "" -- ./compiler/lua54.can:96 +local function addRequire(mod, name, field) -- ./compiler/lua54.can:98 +local req = ("require(%q)%s"):format(mod, field and "." .. field or "") -- ./compiler/lua54.can:99 +if not required[req] then -- ./compiler/lua54.can:100 +requireStr = requireStr .. (("local %s = %s%s"):format(var(name), req, options["newline"])) -- ./compiler/lua54.can:101 +required[req] = true -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +end -- ./compiler/lua54.can:102 +local loop = { -- ./compiler/lua54.can:107 +"While", -- ./compiler/lua54.can:107 +"Repeat", -- ./compiler/lua54.can:107 +"Fornum", -- ./compiler/lua54.can:107 +"Forin", -- ./compiler/lua54.can:107 +"WhileExpr", -- ./compiler/lua54.can:107 +"RepeatExpr", -- ./compiler/lua54.can:107 +"FornumExpr", -- ./compiler/lua54.can:107 +"ForinExpr" -- ./compiler/lua54.can:107 +} -- ./compiler/lua54.can:107 +local func = { -- ./compiler/lua54.can:108 +"Function", -- ./compiler/lua54.can:108 +"TableCompr", -- ./compiler/lua54.can:108 +"DoExpr", -- ./compiler/lua54.can:108 +"WhileExpr", -- ./compiler/lua54.can:108 +"RepeatExpr", -- ./compiler/lua54.can:108 +"IfExpr", -- ./compiler/lua54.can:108 +"FornumExpr", -- ./compiler/lua54.can:108 +"ForinExpr" -- ./compiler/lua54.can:108 +} -- ./compiler/lua54.can:108 +local function any(list, tags, nofollow) -- ./compiler/lua54.can:112 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:112 +local tagsCheck = {} -- ./compiler/lua54.can:113 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:114 +tagsCheck[tag] = true -- ./compiler/lua54.can:115 +end -- ./compiler/lua54.can:115 +local nofollowCheck = {} -- ./compiler/lua54.can:117 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:118 +nofollowCheck[tag] = true -- ./compiler/lua54.can:119 +end -- ./compiler/lua54.can:119 +for _, node in ipairs(list) do -- ./compiler/lua54.can:121 +if type(node) == "table" then -- ./compiler/lua54.can:122 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:123 +return node -- ./compiler/lua54.can:124 +end -- ./compiler/lua54.can:124 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:126 +local r = any(node, tags, nofollow) -- ./compiler/lua54.can:127 +if r then -- ./compiler/lua54.can:128 +return r -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +end -- ./compiler/lua54.can:128 +return nil -- ./compiler/lua54.can:132 +end -- ./compiler/lua54.can:132 +local function search(list, tags, nofollow) -- ./compiler/lua54.can:137 +if nofollow == nil then nofollow = {} end -- ./compiler/lua54.can:137 +local tagsCheck = {} -- ./compiler/lua54.can:138 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:139 +tagsCheck[tag] = true -- ./compiler/lua54.can:140 +end -- ./compiler/lua54.can:140 +local nofollowCheck = {} -- ./compiler/lua54.can:142 +for _, tag in ipairs(nofollow) do -- ./compiler/lua54.can:143 +nofollowCheck[tag] = true -- ./compiler/lua54.can:144 +end -- ./compiler/lua54.can:144 +local found = {} -- ./compiler/lua54.can:146 +for _, node in ipairs(list) do -- ./compiler/lua54.can:147 +if type(node) == "table" then -- ./compiler/lua54.can:148 +if not nofollowCheck[node["tag"]] then -- ./compiler/lua54.can:149 +for _, n in ipairs(search(node, tags, nofollow)) do -- ./compiler/lua54.can:150 +table["insert"](found, n) -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +end -- ./compiler/lua54.can:151 +if tagsCheck[node["tag"]] then -- ./compiler/lua54.can:154 +table["insert"](found, node) -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +end -- ./compiler/lua54.can:155 +return found -- ./compiler/lua54.can:159 +end -- ./compiler/lua54.can:159 +local function all(list, tags) -- ./compiler/lua54.can:163 +for _, node in ipairs(list) do -- ./compiler/lua54.can:164 +local ok = false -- ./compiler/lua54.can:165 +for _, tag in ipairs(tags) do -- ./compiler/lua54.can:166 +if node["tag"] == tag then -- ./compiler/lua54.can:167 +ok = true -- ./compiler/lua54.can:168 +break -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +end -- ./compiler/lua54.can:169 +if not ok then -- ./compiler/lua54.can:172 +return false -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +end -- ./compiler/lua54.can:173 +return true -- ./compiler/lua54.can:176 +end -- ./compiler/lua54.can:176 +local tags -- ./compiler/lua54.can:180 +local function lua(ast, forceTag, ...) -- ./compiler/lua54.can:182 +if options["mapLines"] and ast["pos"] then -- ./compiler/lua54.can:183 +lastInputPos = ast["pos"] -- ./compiler/lua54.can:184 end -- ./compiler/lua54.can:184 -local UNPACK = function(list, i, j) -- ./compiler/lua54.can:188 -return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:189 -end -- ./compiler/lua54.can:189 -local APPEND = function(t, toAppend) -- ./compiler/lua54.can:191 -return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:192 -end -- ./compiler/lua54.can:192 -local CONTINUE_START = function() -- ./compiler/lua54.can:194 -return "do" .. indent() -- ./compiler/lua54.can:195 -end -- ./compiler/lua54.can:195 -local CONTINUE_STOP = function() -- ./compiler/lua54.can:197 -return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:198 -end -- ./compiler/lua54.can:198 -local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:200 -if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:200 -if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:200 -local vars = {} -- ./compiler/lua54.can:201 -local values = {} -- ./compiler/lua54.can:202 -for _, list in ipairs(destructured) do -- ./compiler/lua54.can:203 -for _, v in ipairs(list) do -- ./compiler/lua54.can:204 -local var, val -- ./compiler/lua54.can:205 -if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:206 -var = v -- ./compiler/lua54.can:207 -val = { -- ./compiler/lua54.can:208 -["tag"] = "Index", -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "Id", -- ./compiler/lua54.can:208 -list["id"] -- ./compiler/lua54.can:208 -}, -- ./compiler/lua54.can:208 -{ -- ./compiler/lua54.can:208 -["tag"] = "String", -- ./compiler/lua54.can:208 -v[1] -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -} -- ./compiler/lua54.can:208 -elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:209 -var = v[2] -- ./compiler/lua54.can:210 -val = { -- ./compiler/lua54.can:211 -["tag"] = "Index", -- ./compiler/lua54.can:211 -{ -- ./compiler/lua54.can:211 -["tag"] = "Id", -- ./compiler/lua54.can:211 -list["id"] -- ./compiler/lua54.can:211 -}, -- ./compiler/lua54.can:211 -v[1] -- ./compiler/lua54.can:211 -} -- ./compiler/lua54.can:211 -else -- ./compiler/lua54.can:211 -error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:213 -end -- ./compiler/lua54.can:213 -if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:215 -val = { -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["rightOp"], -- ./compiler/lua54.can:216 -var, -- ./compiler/lua54.can:216 -{ -- ./compiler/lua54.can:216 -["tag"] = "Op", -- ./compiler/lua54.can:216 -destructured["leftOp"], -- ./compiler/lua54.can:216 -val, -- ./compiler/lua54.can:216 -var -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -} -- ./compiler/lua54.can:216 -elseif destructured["rightOp"] then -- ./compiler/lua54.can:217 +return tags[forceTag or ast["tag"]](ast, ...) -- ./compiler/lua54.can:186 +end -- ./compiler/lua54.can:186 +local UNPACK = function(list, i, j) -- ./compiler/lua54.can:190 +return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/lua54.can:191 +end -- ./compiler/lua54.can:191 +local APPEND = function(t, toAppend) -- ./compiler/lua54.can:193 +return "do" .. indent() .. "local " .. var("a") .. " = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(" .. var("a") .. ", 1, " .. var("a") .. ".n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end" -- ./compiler/lua54.can:194 +end -- ./compiler/lua54.can:194 +local CONTINUE_START = function() -- ./compiler/lua54.can:196 +return "do" .. indent() -- ./compiler/lua54.can:197 +end -- ./compiler/lua54.can:197 +local CONTINUE_STOP = function() -- ./compiler/lua54.can:199 +return unindent() .. "end" .. newline() .. "::" .. var("continue") .. "::" -- ./compiler/lua54.can:200 +end -- ./compiler/lua54.can:200 +local DESTRUCTURING_ASSIGN = function(destructured, newlineAfter, noLocal) -- ./compiler/lua54.can:202 +if newlineAfter == nil then newlineAfter = false end -- ./compiler/lua54.can:202 +if noLocal == nil then noLocal = false end -- ./compiler/lua54.can:202 +local vars = {} -- ./compiler/lua54.can:203 +local values = {} -- ./compiler/lua54.can:204 +for _, list in ipairs(destructured) do -- ./compiler/lua54.can:205 +for _, v in ipairs(list) do -- ./compiler/lua54.can:206 +local var, val -- ./compiler/lua54.can:207 +if v["tag"] == "Id" or v["tag"] == "AttributeId" then -- ./compiler/lua54.can:208 +var = v -- ./compiler/lua54.can:209 +val = { -- ./compiler/lua54.can:210 +["tag"] = "Index", -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "Id", -- ./compiler/lua54.can:210 +list["id"] -- ./compiler/lua54.can:210 +}, -- ./compiler/lua54.can:210 +{ -- ./compiler/lua54.can:210 +["tag"] = "String", -- ./compiler/lua54.can:210 +v[1] -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +} -- ./compiler/lua54.can:210 +elseif v["tag"] == "Pair" then -- ./compiler/lua54.can:211 +var = v[2] -- ./compiler/lua54.can:212 +val = { -- ./compiler/lua54.can:213 +["tag"] = "Index", -- ./compiler/lua54.can:213 +{ -- ./compiler/lua54.can:213 +["tag"] = "Id", -- ./compiler/lua54.can:213 +list["id"] -- ./compiler/lua54.can:213 +}, -- ./compiler/lua54.can:213 +v[1] -- ./compiler/lua54.can:213 +} -- ./compiler/lua54.can:213 +else -- ./compiler/lua54.can:213 +error("unknown destructuring element type: " .. tostring(v["tag"])) -- ./compiler/lua54.can:215 +end -- ./compiler/lua54.can:215 +if destructured["rightOp"] and destructured["leftOp"] then -- ./compiler/lua54.can:217 val = { -- ./compiler/lua54.can:218 ["tag"] = "Op", -- ./compiler/lua54.can:218 destructured["rightOp"], -- ./compiler/lua54.can:218 var, -- ./compiler/lua54.can:218 -val -- ./compiler/lua54.can:218 +{ -- ./compiler/lua54.can:218 +["tag"] = "Op", -- ./compiler/lua54.can:218 +destructured["leftOp"], -- ./compiler/lua54.can:218 +val, -- ./compiler/lua54.can:218 +var -- ./compiler/lua54.can:218 } -- ./compiler/lua54.can:218 -elseif destructured["leftOp"] then -- ./compiler/lua54.can:219 +} -- ./compiler/lua54.can:218 +elseif destructured["rightOp"] then -- ./compiler/lua54.can:219 val = { -- ./compiler/lua54.can:220 ["tag"] = "Op", -- ./compiler/lua54.can:220 -destructured["leftOp"], -- ./compiler/lua54.can:220 -val, -- ./compiler/lua54.can:220 -var -- ./compiler/lua54.can:220 +destructured["rightOp"], -- ./compiler/lua54.can:220 +var, -- ./compiler/lua54.can:220 +val -- ./compiler/lua54.can:220 } -- ./compiler/lua54.can:220 -end -- ./compiler/lua54.can:220 -table["insert"](vars, lua(var)) -- ./compiler/lua54.can:222 -table["insert"](values, lua(val)) -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -end -- ./compiler/lua54.can:223 -if # vars > 0 then -- ./compiler/lua54.can:226 -local decl = noLocal and "" or "local " -- ./compiler/lua54.can:227 -if newlineAfter then -- ./compiler/lua54.can:228 -return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:229 -else -- ./compiler/lua54.can:229 -return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:231 -end -- ./compiler/lua54.can:231 +elseif destructured["leftOp"] then -- ./compiler/lua54.can:221 +val = { -- ./compiler/lua54.can:222 +["tag"] = "Op", -- ./compiler/lua54.can:222 +destructured["leftOp"], -- ./compiler/lua54.can:222 +val, -- ./compiler/lua54.can:222 +var -- ./compiler/lua54.can:222 +} -- ./compiler/lua54.can:222 +end -- ./compiler/lua54.can:222 +table["insert"](vars, lua(var)) -- ./compiler/lua54.can:224 +table["insert"](values, lua(val)) -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +end -- ./compiler/lua54.can:225 +if # vars > 0 then -- ./compiler/lua54.can:228 +local decl = noLocal and "" or "local " -- ./compiler/lua54.can:229 +if newlineAfter then -- ./compiler/lua54.can:230 +return decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") .. newline() -- ./compiler/lua54.can:231 else -- ./compiler/lua54.can:231 -return "" -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -end -- ./compiler/lua54.can:234 -tags = setmetatable({ -- ./compiler/lua54.can:239 -["Block"] = function(t) -- ./compiler/lua54.can:241 -local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:242 -if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:243 -hasPush["tag"] = "Return" -- ./compiler/lua54.can:244 -hasPush = false -- ./compiler/lua54.can:245 -end -- ./compiler/lua54.can:245 -local r = push("scope", {}) -- ./compiler/lua54.can:247 -if hasPush then -- ./compiler/lua54.can:248 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:249 -end -- ./compiler/lua54.can:249 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:251 -r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:252 -end -- ./compiler/lua54.can:252 -if t[# t] then -- ./compiler/lua54.can:254 -r = r .. (lua(t[# t])) -- ./compiler/lua54.can:255 -end -- ./compiler/lua54.can:255 -if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:257 -r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:258 -end -- ./compiler/lua54.can:258 -return r .. pop("scope") -- ./compiler/lua54.can:260 -end, -- ./compiler/lua54.can:260 -["Do"] = function(t) -- ./compiler/lua54.can:266 -return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:267 -end, -- ./compiler/lua54.can:267 -["Set"] = function(t) -- ./compiler/lua54.can:270 -local expr = t[# t] -- ./compiler/lua54.can:272 -local vars, values = {}, {} -- ./compiler/lua54.can:273 -local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:274 -for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:275 -if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:276 -table["insert"](destructuringVars, n) -- ./compiler/lua54.can:277 -table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:278 -else -- ./compiler/lua54.can:278 -table["insert"](vars, n) -- ./compiler/lua54.can:280 -table["insert"](values, expr[i]) -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -end -- ./compiler/lua54.can:281 -if # t == 2 or # t == 3 then -- ./compiler/lua54.can:285 -local r = "" -- ./compiler/lua54.can:286 -if # vars > 0 then -- ./compiler/lua54.can:287 -r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:288 -end -- ./compiler/lua54.can:288 -if # destructuringVars > 0 then -- ./compiler/lua54.can:290 -local destructured = {} -- ./compiler/lua54.can:291 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:292 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:293 -end -- ./compiler/lua54.can:293 -return r -- ./compiler/lua54.can:295 -elseif # t == 4 then -- ./compiler/lua54.can:296 -if t[3] == "=" then -- ./compiler/lua54.can:297 -local r = "" -- ./compiler/lua54.can:298 -if # vars > 0 then -- ./compiler/lua54.can:299 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:300 -t[2], -- ./compiler/lua54.can:300 -vars[1], -- ./compiler/lua54.can:300 -{ -- ./compiler/lua54.can:300 -["tag"] = "Paren", -- ./compiler/lua54.can:300 -values[1] -- ./compiler/lua54.can:300 -} -- ./compiler/lua54.can:300 -}, "Op")) -- ./compiler/lua54.can:300 -for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:301 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:302 +return newline() .. decl .. table["concat"](vars, ", ") .. " = " .. table["concat"](values, ", ") -- ./compiler/lua54.can:233 +end -- ./compiler/lua54.can:233 +else -- ./compiler/lua54.can:233 +return "" -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +end -- ./compiler/lua54.can:236 +tags = setmetatable({ -- ./compiler/lua54.can:241 +["Block"] = function(t) -- ./compiler/lua54.can:243 +local hasPush = peek("push") == nil and any(t, { "Push" }, func) -- ./compiler/lua54.can:244 +if hasPush and hasPush == t[# t] then -- ./compiler/lua54.can:245 +hasPush["tag"] = "Return" -- ./compiler/lua54.can:246 +hasPush = false -- ./compiler/lua54.can:247 +end -- ./compiler/lua54.can:247 +local r = push("scope", {}) -- ./compiler/lua54.can:249 +if hasPush then -- ./compiler/lua54.can:250 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:251 +end -- ./compiler/lua54.can:251 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:253 +r = r .. (lua(t[i]) .. newline()) -- ./compiler/lua54.can:254 +end -- ./compiler/lua54.can:254 +if t[# t] then -- ./compiler/lua54.can:256 +r = r .. (lua(t[# t])) -- ./compiler/lua54.can:257 +end -- ./compiler/lua54.can:257 +if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then -- ./compiler/lua54.can:259 +r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push")) -- ./compiler/lua54.can:260 +end -- ./compiler/lua54.can:260 +return r .. pop("scope") -- ./compiler/lua54.can:262 +end, -- ./compiler/lua54.can:262 +["Do"] = function(t) -- ./compiler/lua54.can:268 +return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end" -- ./compiler/lua54.can:269 +end, -- ./compiler/lua54.can:269 +["Set"] = function(t) -- ./compiler/lua54.can:272 +local expr = t[# t] -- ./compiler/lua54.can:274 +local vars, values = {}, {} -- ./compiler/lua54.can:275 +local destructuringVars, destructuringValues = {}, {} -- ./compiler/lua54.can:276 +for i, n in ipairs(t[1]) do -- ./compiler/lua54.can:277 +if n["tag"] == "DestructuringId" then -- ./compiler/lua54.can:278 +table["insert"](destructuringVars, n) -- ./compiler/lua54.can:279 +table["insert"](destructuringValues, expr[i]) -- ./compiler/lua54.can:280 +else -- ./compiler/lua54.can:280 +table["insert"](vars, n) -- ./compiler/lua54.can:282 +table["insert"](values, expr[i]) -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +end -- ./compiler/lua54.can:283 +if # t == 2 or # t == 3 then -- ./compiler/lua54.can:287 +local r = "" -- ./compiler/lua54.can:288 +if # vars > 0 then -- ./compiler/lua54.can:289 +r = lua(vars, "_lhs") .. " = " .. lua(values, "_lhs") -- ./compiler/lua54.can:290 +end -- ./compiler/lua54.can:290 +if # destructuringVars > 0 then -- ./compiler/lua54.can:292 +local destructured = {} -- ./compiler/lua54.can:293 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:294 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:295 +end -- ./compiler/lua54.can:295 +return r -- ./compiler/lua54.can:297 +elseif # t == 4 then -- ./compiler/lua54.can:298 +if t[3] == "=" then -- ./compiler/lua54.can:299 +local r = "" -- ./compiler/lua54.can:300 +if # vars > 0 then -- ./compiler/lua54.can:301 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:302 t[2], -- ./compiler/lua54.can:302 -vars[i], -- ./compiler/lua54.can:302 +vars[1], -- ./compiler/lua54.can:302 { -- ./compiler/lua54.can:302 ["tag"] = "Paren", -- ./compiler/lua54.can:302 -values[i] -- ./compiler/lua54.can:302 +values[1] -- ./compiler/lua54.can:302 } -- ./compiler/lua54.can:302 }, "Op")) -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -end -- ./compiler/lua54.can:302 -if # destructuringVars > 0 then -- ./compiler/lua54.can:305 -local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:306 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:307 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:308 -end -- ./compiler/lua54.can:308 -return r -- ./compiler/lua54.can:310 -else -- ./compiler/lua54.can:310 -local r = "" -- ./compiler/lua54.can:312 -if # vars > 0 then -- ./compiler/lua54.can:313 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:314 -t[3], -- ./compiler/lua54.can:314 -{ -- ./compiler/lua54.can:314 -["tag"] = "Paren", -- ./compiler/lua54.can:314 -values[1] -- ./compiler/lua54.can:314 -}, -- ./compiler/lua54.can:314 -vars[1] -- ./compiler/lua54.can:314 -}, "Op")) -- ./compiler/lua54.can:314 -for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:315 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:316 +for i = 2, math["min"](# t[4], # vars), 1 do -- ./compiler/lua54.can:303 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:304 +t[2], -- ./compiler/lua54.can:304 +vars[i], -- ./compiler/lua54.can:304 +{ -- ./compiler/lua54.can:304 +["tag"] = "Paren", -- ./compiler/lua54.can:304 +values[i] -- ./compiler/lua54.can:304 +} -- ./compiler/lua54.can:304 +}, "Op")) -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +end -- ./compiler/lua54.can:304 +if # destructuringVars > 0 then -- ./compiler/lua54.can:307 +local destructured = { ["rightOp"] = t[2] } -- ./compiler/lua54.can:308 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:309 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:310 +end -- ./compiler/lua54.can:310 +return r -- ./compiler/lua54.can:312 +else -- ./compiler/lua54.can:312 +local r = "" -- ./compiler/lua54.can:314 +if # vars > 0 then -- ./compiler/lua54.can:315 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:316 t[3], -- ./compiler/lua54.can:316 { -- ./compiler/lua54.can:316 ["tag"] = "Paren", -- ./compiler/lua54.can:316 -values[i] -- ./compiler/lua54.can:316 +values[1] -- ./compiler/lua54.can:316 }, -- ./compiler/lua54.can:316 -vars[i] -- ./compiler/lua54.can:316 +vars[1] -- ./compiler/lua54.can:316 }, "Op")) -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -end -- ./compiler/lua54.can:316 -if # destructuringVars > 0 then -- ./compiler/lua54.can:319 -local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:320 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:321 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:322 -end -- ./compiler/lua54.can:322 -return r -- ./compiler/lua54.can:324 +for i = 2, math["min"](# t[4], # t[1]), 1 do -- ./compiler/lua54.can:317 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:318 +t[3], -- ./compiler/lua54.can:318 +{ -- ./compiler/lua54.can:318 +["tag"] = "Paren", -- ./compiler/lua54.can:318 +values[i] -- ./compiler/lua54.can:318 +}, -- ./compiler/lua54.can:318 +vars[i] -- ./compiler/lua54.can:318 +}, "Op")) -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +end -- ./compiler/lua54.can:318 +if # destructuringVars > 0 then -- ./compiler/lua54.can:321 +local destructured = { ["leftOp"] = t[3] } -- ./compiler/lua54.can:322 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:323 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:324 end -- ./compiler/lua54.can:324 -else -- ./compiler/lua54.can:324 -local r = "" -- ./compiler/lua54.can:327 -if # vars > 0 then -- ./compiler/lua54.can:328 -r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:329 -t[2], -- ./compiler/lua54.can:329 -vars[1], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Op", -- ./compiler/lua54.can:329 -t[4], -- ./compiler/lua54.can:329 -{ -- ./compiler/lua54.can:329 -["tag"] = "Paren", -- ./compiler/lua54.can:329 -values[1] -- ./compiler/lua54.can:329 -}, -- ./compiler/lua54.can:329 -vars[1] -- ./compiler/lua54.can:329 -} -- ./compiler/lua54.can:329 -}, "Op")) -- ./compiler/lua54.can:329 -for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:330 -r = r .. (", " .. lua({ -- ./compiler/lua54.can:331 +return r -- ./compiler/lua54.can:326 +end -- ./compiler/lua54.can:326 +else -- ./compiler/lua54.can:326 +local r = "" -- ./compiler/lua54.can:329 +if # vars > 0 then -- ./compiler/lua54.can:330 +r = r .. (lua(vars, "_lhs") .. " = " .. lua({ -- ./compiler/lua54.can:331 t[2], -- ./compiler/lua54.can:331 -vars[i], -- ./compiler/lua54.can:331 +vars[1], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Op", -- ./compiler/lua54.can:331 t[4], -- ./compiler/lua54.can:331 { -- ./compiler/lua54.can:331 ["tag"] = "Paren", -- ./compiler/lua54.can:331 -values[i] -- ./compiler/lua54.can:331 +values[1] -- ./compiler/lua54.can:331 }, -- ./compiler/lua54.can:331 -vars[i] -- ./compiler/lua54.can:331 +vars[1] -- ./compiler/lua54.can:331 } -- ./compiler/lua54.can:331 }, "Op")) -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -end -- ./compiler/lua54.can:331 -if # destructuringVars > 0 then -- ./compiler/lua54.can:334 -local destructured = { -- ./compiler/lua54.can:335 -["rightOp"] = t[2], -- ./compiler/lua54.can:335 -["leftOp"] = t[4] -- ./compiler/lua54.can:335 -} -- ./compiler/lua54.can:335 -r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:336 -return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:337 -end -- ./compiler/lua54.can:337 -return r -- ./compiler/lua54.can:339 +for i = 2, math["min"](# t[5], # t[1]), 1 do -- ./compiler/lua54.can:332 +r = r .. (", " .. lua({ -- ./compiler/lua54.can:333 +t[2], -- ./compiler/lua54.can:333 +vars[i], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Op", -- ./compiler/lua54.can:333 +t[4], -- ./compiler/lua54.can:333 +{ -- ./compiler/lua54.can:333 +["tag"] = "Paren", -- ./compiler/lua54.can:333 +values[i] -- ./compiler/lua54.can:333 +}, -- ./compiler/lua54.can:333 +vars[i] -- ./compiler/lua54.can:333 +} -- ./compiler/lua54.can:333 +}, "Op")) -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +end -- ./compiler/lua54.can:333 +if # destructuringVars > 0 then -- ./compiler/lua54.can:336 +local destructured = { -- ./compiler/lua54.can:337 +["rightOp"] = t[2], -- ./compiler/lua54.can:337 +["leftOp"] = t[4] -- ./compiler/lua54.can:337 +} -- ./compiler/lua54.can:337 +r = r .. ("local " .. push("destructuring", destructured) .. lua(destructuringVars, "_lhs") .. pop("destructuring") .. " = " .. lua(destructuringValues, "_lhs")) -- ./compiler/lua54.can:338 +return r .. DESTRUCTURING_ASSIGN(destructured, nil, true) -- ./compiler/lua54.can:339 end -- ./compiler/lua54.can:339 -end, -- ./compiler/lua54.can:339 -["While"] = function(t) -- ./compiler/lua54.can:343 -local r = "" -- ./compiler/lua54.can:344 -local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:345 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:346 -if # lets > 0 then -- ./compiler/lua54.can:347 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:348 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:349 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -end -- ./compiler/lua54.can:350 -r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:353 -if # lets > 0 then -- ./compiler/lua54.can:354 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:355 -end -- ./compiler/lua54.can:355 -if hasContinue then -- ./compiler/lua54.can:357 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:358 -end -- ./compiler/lua54.can:358 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:360 -if hasContinue then -- ./compiler/lua54.can:361 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:362 -end -- ./compiler/lua54.can:362 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:364 -if # lets > 0 then -- ./compiler/lua54.can:365 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:366 -r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:367 -end -- ./compiler/lua54.can:367 -r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:369 +return r -- ./compiler/lua54.can:341 +end -- ./compiler/lua54.can:341 +end, -- ./compiler/lua54.can:341 +["While"] = function(t) -- ./compiler/lua54.can:345 +local r = "" -- ./compiler/lua54.can:346 +local hasContinue = any(t[2], { "Continue" }, loop) -- ./compiler/lua54.can:347 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:348 +if # lets > 0 then -- ./compiler/lua54.can:349 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:350 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:351 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +end -- ./compiler/lua54.can:352 +r = r .. ("while " .. lua(t[1]) .. " do" .. indent()) -- ./compiler/lua54.can:355 +if # lets > 0 then -- ./compiler/lua54.can:356 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:357 +end -- ./compiler/lua54.can:357 +if hasContinue then -- ./compiler/lua54.can:359 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:360 +end -- ./compiler/lua54.can:360 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:362 +if hasContinue then -- ./compiler/lua54.can:363 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:364 +end -- ./compiler/lua54.can:364 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:366 +if # lets > 0 then -- ./compiler/lua54.can:367 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:368 +r = r .. (newline() .. lua(l, "Set")) -- ./compiler/lua54.can:369 end -- ./compiler/lua54.can:369 -return r -- ./compiler/lua54.can:371 -end, -- ./compiler/lua54.can:371 -["Repeat"] = function(t) -- ./compiler/lua54.can:374 -local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:375 -local r = "repeat" .. indent() -- ./compiler/lua54.can:376 -if hasContinue then -- ./compiler/lua54.can:377 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:378 -end -- ./compiler/lua54.can:378 -r = r .. (lua(t[1])) -- ./compiler/lua54.can:380 -if hasContinue then -- ./compiler/lua54.can:381 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:382 -end -- ./compiler/lua54.can:382 -r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:384 -return r -- ./compiler/lua54.can:385 -end, -- ./compiler/lua54.can:385 -["If"] = function(t) -- ./compiler/lua54.can:388 -local r = "" -- ./compiler/lua54.can:389 -local toClose = 0 -- ./compiler/lua54.can:390 -local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:391 -if # lets > 0 then -- ./compiler/lua54.can:392 -r = r .. ("do" .. indent()) -- ./compiler/lua54.can:393 -toClose = toClose + (1) -- ./compiler/lua54.can:394 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:395 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -end -- ./compiler/lua54.can:396 -r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:399 -for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:400 -lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:401 -if # lets > 0 then -- ./compiler/lua54.can:402 -r = r .. ("else" .. indent()) -- ./compiler/lua54.can:403 -toClose = toClose + (1) -- ./compiler/lua54.can:404 -for _, l in ipairs(lets) do -- ./compiler/lua54.can:405 -r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:406 -end -- ./compiler/lua54.can:406 -else -- ./compiler/lua54.can:406 -r = r .. ("else") -- ./compiler/lua54.can:409 -end -- ./compiler/lua54.can:409 -r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:411 +r = r .. (unindent() .. "end" .. unindent() .. "end") -- ./compiler/lua54.can:371 +end -- ./compiler/lua54.can:371 +return r -- ./compiler/lua54.can:373 +end, -- ./compiler/lua54.can:373 +["Repeat"] = function(t) -- ./compiler/lua54.can:376 +local hasContinue = any(t[1], { "Continue" }, loop) -- ./compiler/lua54.can:377 +local r = "repeat" .. indent() -- ./compiler/lua54.can:378 +if hasContinue then -- ./compiler/lua54.can:379 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:380 +end -- ./compiler/lua54.can:380 +r = r .. (lua(t[1])) -- ./compiler/lua54.can:382 +if hasContinue then -- ./compiler/lua54.can:383 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:384 +end -- ./compiler/lua54.can:384 +r = r .. (unindent() .. "until " .. lua(t[2])) -- ./compiler/lua54.can:386 +return r -- ./compiler/lua54.can:387 +end, -- ./compiler/lua54.can:387 +["If"] = function(t) -- ./compiler/lua54.can:390 +local r = "" -- ./compiler/lua54.can:391 +local toClose = 0 -- ./compiler/lua54.can:392 +local lets = search({ t[1] }, { "LetExpr" }) -- ./compiler/lua54.can:393 +if # lets > 0 then -- ./compiler/lua54.can:394 +r = r .. ("do" .. indent()) -- ./compiler/lua54.can:395 +toClose = toClose + (1) -- ./compiler/lua54.can:396 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:397 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +end -- ./compiler/lua54.can:398 +r = r .. ("if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()) -- ./compiler/lua54.can:401 +for i = 3, # t - 1, 2 do -- ./compiler/lua54.can:402 +lets = search({ t[i] }, { "LetExpr" }) -- ./compiler/lua54.can:403 +if # lets > 0 then -- ./compiler/lua54.can:404 +r = r .. ("else" .. indent()) -- ./compiler/lua54.can:405 +toClose = toClose + (1) -- ./compiler/lua54.can:406 +for _, l in ipairs(lets) do -- ./compiler/lua54.can:407 +r = r .. (lua(l, "Let") .. newline()) -- ./compiler/lua54.can:408 +end -- ./compiler/lua54.can:408 +else -- ./compiler/lua54.can:408 +r = r .. ("else") -- ./compiler/lua54.can:411 end -- ./compiler/lua54.can:411 -if # t % 2 == 1 then -- ./compiler/lua54.can:413 -r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:414 -end -- ./compiler/lua54.can:414 -r = r .. ("end") -- ./compiler/lua54.can:416 -for i = 1, toClose do -- ./compiler/lua54.can:417 -r = r .. (unindent() .. "end") -- ./compiler/lua54.can:418 -end -- ./compiler/lua54.can:418 -return r -- ./compiler/lua54.can:420 -end, -- ./compiler/lua54.can:420 -["Fornum"] = function(t) -- ./compiler/lua54.can:423 -local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:424 -if # t == 5 then -- ./compiler/lua54.can:425 -local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:426 -r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:427 -if hasContinue then -- ./compiler/lua54.can:428 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:429 -end -- ./compiler/lua54.can:429 -r = r .. (lua(t[5])) -- ./compiler/lua54.can:431 -if hasContinue then -- ./compiler/lua54.can:432 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:433 -end -- ./compiler/lua54.can:433 -return r .. unindent() .. "end" -- ./compiler/lua54.can:435 -else -- ./compiler/lua54.can:435 -local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:437 -r = r .. (" do" .. indent()) -- ./compiler/lua54.can:438 -if hasContinue then -- ./compiler/lua54.can:439 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:440 -end -- ./compiler/lua54.can:440 -r = r .. (lua(t[4])) -- ./compiler/lua54.can:442 -if hasContinue then -- ./compiler/lua54.can:443 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:444 -end -- ./compiler/lua54.can:444 -return r .. unindent() .. "end" -- ./compiler/lua54.can:446 +r = r .. ("if " .. lua(t[i]) .. " then" .. indent() .. lua(t[i + 1]) .. unindent()) -- ./compiler/lua54.can:413 +end -- ./compiler/lua54.can:413 +if # t % 2 == 1 then -- ./compiler/lua54.can:415 +r = r .. ("else" .. indent() .. lua(t[# t]) .. unindent()) -- ./compiler/lua54.can:416 +end -- ./compiler/lua54.can:416 +r = r .. ("end") -- ./compiler/lua54.can:418 +for i = 1, toClose do -- ./compiler/lua54.can:419 +r = r .. (unindent() .. "end") -- ./compiler/lua54.can:420 +end -- ./compiler/lua54.can:420 +return r -- ./compiler/lua54.can:422 +end, -- ./compiler/lua54.can:422 +["Fornum"] = function(t) -- ./compiler/lua54.can:425 +local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3]) -- ./compiler/lua54.can:426 +if # t == 5 then -- ./compiler/lua54.can:427 +local hasContinue = any(t[5], { "Continue" }, loop) -- ./compiler/lua54.can:428 +r = r .. (", " .. lua(t[4]) .. " do" .. indent()) -- ./compiler/lua54.can:429 +if hasContinue then -- ./compiler/lua54.can:430 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:431 +end -- ./compiler/lua54.can:431 +r = r .. (lua(t[5])) -- ./compiler/lua54.can:433 +if hasContinue then -- ./compiler/lua54.can:434 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:435 +end -- ./compiler/lua54.can:435 +return r .. unindent() .. "end" -- ./compiler/lua54.can:437 +else -- ./compiler/lua54.can:437 +local hasContinue = any(t[4], { "Continue" }, loop) -- ./compiler/lua54.can:439 +r = r .. (" do" .. indent()) -- ./compiler/lua54.can:440 +if hasContinue then -- ./compiler/lua54.can:441 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:442 +end -- ./compiler/lua54.can:442 +r = r .. (lua(t[4])) -- ./compiler/lua54.can:444 +if hasContinue then -- ./compiler/lua54.can:445 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:446 end -- ./compiler/lua54.can:446 -end, -- ./compiler/lua54.can:446 -["Forin"] = function(t) -- ./compiler/lua54.can:450 -local destructured = {} -- ./compiler/lua54.can:451 -local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:452 -local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:453 -if hasContinue then -- ./compiler/lua54.can:454 -r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:455 -end -- ./compiler/lua54.can:455 -r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:457 -if hasContinue then -- ./compiler/lua54.can:458 -r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:459 -end -- ./compiler/lua54.can:459 -return r .. unindent() .. "end" -- ./compiler/lua54.can:461 -end, -- ./compiler/lua54.can:461 -["Local"] = function(t) -- ./compiler/lua54.can:464 -local destructured = {} -- ./compiler/lua54.can:465 -local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:466 -if t[2][1] then -- ./compiler/lua54.can:467 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:468 -end -- ./compiler/lua54.can:468 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:470 -end, -- ./compiler/lua54.can:470 -["Let"] = function(t) -- ./compiler/lua54.can:473 -local destructured = {} -- ./compiler/lua54.can:474 -local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:475 -local r = "local " .. nameList -- ./compiler/lua54.can:476 -if t[2][1] then -- ./compiler/lua54.can:477 -if all(t[2], { -- ./compiler/lua54.can:478 -"Nil", -- ./compiler/lua54.can:478 -"Dots", -- ./compiler/lua54.can:478 -"Boolean", -- ./compiler/lua54.can:478 -"Number", -- ./compiler/lua54.can:478 -"String" -- ./compiler/lua54.can:478 -}) then -- ./compiler/lua54.can:478 -r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:479 -else -- ./compiler/lua54.can:479 -r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -end -- ./compiler/lua54.can:481 -return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:484 -end, -- ./compiler/lua54.can:484 -["Localrec"] = function(t) -- ./compiler/lua54.can:487 -return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:488 -end, -- ./compiler/lua54.can:488 -["Goto"] = function(t) -- ./compiler/lua54.can:491 -return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:492 -end, -- ./compiler/lua54.can:492 -["Label"] = function(t) -- ./compiler/lua54.can:495 -return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:496 -end, -- ./compiler/lua54.can:496 -["Return"] = function(t) -- ./compiler/lua54.can:499 -local push = peek("push") -- ./compiler/lua54.can:500 -if push then -- ./compiler/lua54.can:501 -local r = "" -- ./compiler/lua54.can:502 -for _, val in ipairs(t) do -- ./compiler/lua54.can:503 -r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:504 -end -- ./compiler/lua54.can:504 -return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:506 -else -- ./compiler/lua54.can:506 -return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:508 -end -- ./compiler/lua54.can:508 -end, -- ./compiler/lua54.can:508 -["Push"] = function(t) -- ./compiler/lua54.can:512 -local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:513 -r = "" -- ./compiler/lua54.can:514 -for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:515 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:516 -end -- ./compiler/lua54.can:516 -if t[# t] then -- ./compiler/lua54.can:518 -if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:519 -r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:520 -else -- ./compiler/lua54.can:520 -r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -end -- ./compiler/lua54.can:522 -return r -- ./compiler/lua54.can:525 -end, -- ./compiler/lua54.can:525 -["Break"] = function() -- ./compiler/lua54.can:528 -return "break" -- ./compiler/lua54.can:529 -end, -- ./compiler/lua54.can:529 -["Continue"] = function() -- ./compiler/lua54.can:532 -return "goto " .. var("continue") -- ./compiler/lua54.can:533 -end, -- ./compiler/lua54.can:533 -["Nil"] = function() -- ./compiler/lua54.can:540 -return "nil" -- ./compiler/lua54.can:541 -end, -- ./compiler/lua54.can:541 -["Dots"] = function() -- ./compiler/lua54.can:544 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:545 -if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:546 -nomacro["variables"]["..."] = true -- ./compiler/lua54.can:547 -local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:548 -nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:549 -return r -- ./compiler/lua54.can:550 -else -- ./compiler/lua54.can:550 -return "..." -- ./compiler/lua54.can:552 -end -- ./compiler/lua54.can:552 -end, -- ./compiler/lua54.can:552 -["Boolean"] = function(t) -- ./compiler/lua54.can:556 -return tostring(t[1]) -- ./compiler/lua54.can:557 -end, -- ./compiler/lua54.can:557 -["Number"] = function(t) -- ./compiler/lua54.can:560 -return tostring(t[1]) -- ./compiler/lua54.can:561 -end, -- ./compiler/lua54.can:561 -["String"] = function(t) -- ./compiler/lua54.can:564 -return ("%q"):format(t[1]) -- ./compiler/lua54.can:565 -end, -- ./compiler/lua54.can:565 -["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:568 -local r = "(" -- ./compiler/lua54.can:569 -local decl = {} -- ./compiler/lua54.can:570 -if t[1][1] then -- ./compiler/lua54.can:571 -if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:572 -local id = lua(t[1][1][1]) -- ./compiler/lua54.can:573 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:574 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:575 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:576 -r = r .. (id) -- ./compiler/lua54.can:577 -else -- ./compiler/lua54.can:577 -r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:579 -end -- ./compiler/lua54.can:579 -for i = 2, # t[1], 1 do -- ./compiler/lua54.can:581 -if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:582 -local id = lua(t[1][i][1]) -- ./compiler/lua54.can:583 -indentLevel = indentLevel + (1) -- ./compiler/lua54.can:584 -table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:585 -indentLevel = indentLevel - (1) -- ./compiler/lua54.can:586 -r = r .. (", " .. id) -- ./compiler/lua54.can:587 -else -- ./compiler/lua54.can:587 -r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -end -- ./compiler/lua54.can:589 -r = r .. (")" .. indent()) -- ./compiler/lua54.can:593 -for _, d in ipairs(decl) do -- ./compiler/lua54.can:594 -r = r .. (d .. newline()) -- ./compiler/lua54.can:595 -end -- ./compiler/lua54.can:595 -if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:597 -t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:598 -end -- ./compiler/lua54.can:598 -local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:600 -if hasPush then -- ./compiler/lua54.can:601 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:602 -else -- ./compiler/lua54.can:602 -push("push", false) -- ./compiler/lua54.can:604 -end -- ./compiler/lua54.can:604 -r = r .. (lua(t[2])) -- ./compiler/lua54.can:606 -if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:607 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:608 -end -- ./compiler/lua54.can:608 -pop("push") -- ./compiler/lua54.can:610 -return r .. unindent() .. "end" -- ./compiler/lua54.can:611 -end, -- ./compiler/lua54.can:611 -["Function"] = function(t) -- ./compiler/lua54.can:613 -return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:614 -end, -- ./compiler/lua54.can:614 -["Pair"] = function(t) -- ./compiler/lua54.can:617 -return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:618 -end, -- ./compiler/lua54.can:618 -["Table"] = function(t) -- ./compiler/lua54.can:620 -if # t == 0 then -- ./compiler/lua54.can:621 -return "{}" -- ./compiler/lua54.can:622 -elseif # t == 1 then -- ./compiler/lua54.can:623 -return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:624 -else -- ./compiler/lua54.can:624 -return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:626 -end -- ./compiler/lua54.can:626 -end, -- ./compiler/lua54.can:626 -["TableCompr"] = function(t) -- ./compiler/lua54.can:630 -return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:631 -end, -- ./compiler/lua54.can:631 -["Op"] = function(t) -- ./compiler/lua54.can:634 -local r -- ./compiler/lua54.can:635 -if # t == 2 then -- ./compiler/lua54.can:636 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:637 -r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:638 -else -- ./compiler/lua54.can:638 -r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:640 -end -- ./compiler/lua54.can:640 +return r .. unindent() .. "end" -- ./compiler/lua54.can:448 +end -- ./compiler/lua54.can:448 +end, -- ./compiler/lua54.can:448 +["Forin"] = function(t) -- ./compiler/lua54.can:452 +local destructured = {} -- ./compiler/lua54.can:453 +local hasContinue = any(t[3], { "Continue" }, loop) -- ./compiler/lua54.can:454 +local r = "for " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() -- ./compiler/lua54.can:455 +if hasContinue then -- ./compiler/lua54.can:456 +r = r .. (CONTINUE_START()) -- ./compiler/lua54.can:457 +end -- ./compiler/lua54.can:457 +r = r .. (DESTRUCTURING_ASSIGN(destructured, true) .. lua(t[3])) -- ./compiler/lua54.can:459 +if hasContinue then -- ./compiler/lua54.can:460 +r = r .. (CONTINUE_STOP()) -- ./compiler/lua54.can:461 +end -- ./compiler/lua54.can:461 +return r .. unindent() .. "end" -- ./compiler/lua54.can:463 +end, -- ./compiler/lua54.can:463 +["Local"] = function(t) -- ./compiler/lua54.can:466 +local destructured = {} -- ./compiler/lua54.can:467 +local r = "local " .. push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:468 +if t[2][1] then -- ./compiler/lua54.can:469 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:470 +end -- ./compiler/lua54.can:470 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:472 +end, -- ./compiler/lua54.can:472 +["Let"] = function(t) -- ./compiler/lua54.can:475 +local destructured = {} -- ./compiler/lua54.can:476 +local nameList = push("destructuring", destructured) .. lua(t[1], "_lhs") .. pop("destructuring") -- ./compiler/lua54.can:477 +local r = "local " .. nameList -- ./compiler/lua54.can:478 +if t[2][1] then -- ./compiler/lua54.can:479 +if all(t[2], { -- ./compiler/lua54.can:480 +"Nil", -- ./compiler/lua54.can:480 +"Dots", -- ./compiler/lua54.can:480 +"Boolean", -- ./compiler/lua54.can:480 +"Number", -- ./compiler/lua54.can:480 +"String" -- ./compiler/lua54.can:480 +}) then -- ./compiler/lua54.can:480 +r = r .. (" = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:481 +else -- ./compiler/lua54.can:481 +r = r .. (newline() .. nameList .. " = " .. lua(t[2], "_lhs")) -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +end -- ./compiler/lua54.can:483 +return r .. DESTRUCTURING_ASSIGN(destructured) -- ./compiler/lua54.can:486 +end, -- ./compiler/lua54.can:486 +["Localrec"] = function(t) -- ./compiler/lua54.can:489 +return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword") -- ./compiler/lua54.can:490 +end, -- ./compiler/lua54.can:490 +["Goto"] = function(t) -- ./compiler/lua54.can:493 +return "goto " .. lua(t, "Id") -- ./compiler/lua54.can:494 +end, -- ./compiler/lua54.can:494 +["Label"] = function(t) -- ./compiler/lua54.can:497 +return "::" .. lua(t, "Id") .. "::" -- ./compiler/lua54.can:498 +end, -- ./compiler/lua54.can:498 +["Return"] = function(t) -- ./compiler/lua54.can:501 +local push = peek("push") -- ./compiler/lua54.can:502 +if push then -- ./compiler/lua54.can:503 +local r = "" -- ./compiler/lua54.can:504 +for _, val in ipairs(t) do -- ./compiler/lua54.can:505 +r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()) -- ./compiler/lua54.can:506 +end -- ./compiler/lua54.can:506 +return r .. "return " .. UNPACK(push) -- ./compiler/lua54.can:508 +else -- ./compiler/lua54.can:508 +return "return " .. lua(t, "_lhs") -- ./compiler/lua54.can:510 +end -- ./compiler/lua54.can:510 +end, -- ./compiler/lua54.can:510 +["Push"] = function(t) -- ./compiler/lua54.can:514 +local var = assert(peek("push"), "no context given for push") -- ./compiler/lua54.can:515 +r = "" -- ./compiler/lua54.can:516 +for i = 1, # t - 1, 1 do -- ./compiler/lua54.can:517 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[i]) .. newline()) -- ./compiler/lua54.can:518 +end -- ./compiler/lua54.can:518 +if t[# t] then -- ./compiler/lua54.can:520 +if t[# t]["tag"] == "Call" then -- ./compiler/lua54.can:521 +r = r .. (APPEND(var, lua(t[# t]))) -- ./compiler/lua54.can:522 +else -- ./compiler/lua54.can:522 +r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t])) -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +end -- ./compiler/lua54.can:524 +return r -- ./compiler/lua54.can:527 +end, -- ./compiler/lua54.can:527 +["Break"] = function() -- ./compiler/lua54.can:530 +return "break" -- ./compiler/lua54.can:531 +end, -- ./compiler/lua54.can:531 +["Continue"] = function() -- ./compiler/lua54.can:534 +return "goto " .. var("continue") -- ./compiler/lua54.can:535 +end, -- ./compiler/lua54.can:535 +["Nil"] = function() -- ./compiler/lua54.can:542 +return "nil" -- ./compiler/lua54.can:543 +end, -- ./compiler/lua54.can:543 +["Dots"] = function() -- ./compiler/lua54.can:546 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:547 +if macroargs and not nomacro["variables"]["..."] and macroargs["..."] then -- ./compiler/lua54.can:548 +nomacro["variables"]["..."] = true -- ./compiler/lua54.can:549 +local r = lua(macroargs["..."], "_lhs") -- ./compiler/lua54.can:550 +nomacro["variables"]["..."] = nil -- ./compiler/lua54.can:551 +return r -- ./compiler/lua54.can:552 +else -- ./compiler/lua54.can:552 +return "..." -- ./compiler/lua54.can:554 +end -- ./compiler/lua54.can:554 +end, -- ./compiler/lua54.can:554 +["Boolean"] = function(t) -- ./compiler/lua54.can:558 +return tostring(t[1]) -- ./compiler/lua54.can:559 +end, -- ./compiler/lua54.can:559 +["Number"] = function(t) -- ./compiler/lua54.can:562 +return tostring(t[1]) -- ./compiler/lua54.can:563 +end, -- ./compiler/lua54.can:563 +["String"] = function(t) -- ./compiler/lua54.can:566 +return ("%q"):format(t[1]) -- ./compiler/lua54.can:567 +end, -- ./compiler/lua54.can:567 +["_functionWithoutKeyword"] = function(t) -- ./compiler/lua54.can:570 +local r = "(" -- ./compiler/lua54.can:571 +local decl = {} -- ./compiler/lua54.can:572 +if t[1][1] then -- ./compiler/lua54.can:573 +if t[1][1]["tag"] == "ParPair" then -- ./compiler/lua54.can:574 +local id = lua(t[1][1][1]) -- ./compiler/lua54.can:575 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:576 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][1][2]) .. " end") -- ./compiler/lua54.can:577 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:578 +r = r .. (id) -- ./compiler/lua54.can:579 +else -- ./compiler/lua54.can:579 +r = r .. (lua(t[1][1])) -- ./compiler/lua54.can:581 +end -- ./compiler/lua54.can:581 +for i = 2, # t[1], 1 do -- ./compiler/lua54.can:583 +if t[1][i]["tag"] == "ParPair" then -- ./compiler/lua54.can:584 +local id = lua(t[1][i][1]) -- ./compiler/lua54.can:585 +indentLevel = indentLevel + (1) -- ./compiler/lua54.can:586 +table["insert"](decl, "if " .. id .. " == nil then " .. id .. " = " .. lua(t[1][i][2]) .. " end") -- ./compiler/lua54.can:587 +indentLevel = indentLevel - (1) -- ./compiler/lua54.can:588 +r = r .. (", " .. id) -- ./compiler/lua54.can:589 +else -- ./compiler/lua54.can:589 +r = r .. (", " .. lua(t[1][i])) -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +end -- ./compiler/lua54.can:591 +r = r .. (")" .. indent()) -- ./compiler/lua54.can:595 +for _, d in ipairs(decl) do -- ./compiler/lua54.can:596 +r = r .. (d .. newline()) -- ./compiler/lua54.can:597 +end -- ./compiler/lua54.can:597 +if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then -- ./compiler/lua54.can:599 +t[2][# t[2]]["tag"] = "Return" -- ./compiler/lua54.can:600 +end -- ./compiler/lua54.can:600 +local hasPush = any(t[2], { "Push" }, func) -- ./compiler/lua54.can:602 +if hasPush then -- ./compiler/lua54.can:603 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:604 +else -- ./compiler/lua54.can:604 +push("push", false) -- ./compiler/lua54.can:606 +end -- ./compiler/lua54.can:606 +r = r .. (lua(t[2])) -- ./compiler/lua54.can:608 +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then -- ./compiler/lua54.can:609 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:610 +end -- ./compiler/lua54.can:610 +pop("push") -- ./compiler/lua54.can:612 +return r .. unindent() .. "end" -- ./compiler/lua54.can:613 +end, -- ./compiler/lua54.can:613 +["Function"] = function(t) -- ./compiler/lua54.can:615 +return "function" .. lua(t, "_functionWithoutKeyword") -- ./compiler/lua54.can:616 +end, -- ./compiler/lua54.can:616 +["Pair"] = function(t) -- ./compiler/lua54.can:619 +return "[" .. lua(t[1]) .. "] = " .. lua(t[2]) -- ./compiler/lua54.can:620 +end, -- ./compiler/lua54.can:620 +["Table"] = function(t) -- ./compiler/lua54.can:622 +if # t == 0 then -- ./compiler/lua54.can:623 +return "{}" -- ./compiler/lua54.can:624 +elseif # t == 1 then -- ./compiler/lua54.can:625 +return "{ " .. lua(t, "_lhs") .. " }" -- ./compiler/lua54.can:626 +else -- ./compiler/lua54.can:626 +return "{" .. indent() .. lua(t, "_lhs", nil, true) .. unindent() .. "}" -- ./compiler/lua54.can:628 +end -- ./compiler/lua54.can:628 +end, -- ./compiler/lua54.can:628 +["TableCompr"] = function(t) -- ./compiler/lua54.can:632 +return push("push", "self") .. "(function()" .. indent() .. "local self = {}" .. newline() .. lua(t[1]) .. newline() .. "return self" .. unindent() .. "end)()" .. pop("push") -- ./compiler/lua54.can:633 +end, -- ./compiler/lua54.can:633 +["Op"] = function(t) -- ./compiler/lua54.can:636 +local r -- ./compiler/lua54.can:637 +if # t == 2 then -- ./compiler/lua54.can:638 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:639 +r = tags["_opid"][t[1]] .. " " .. lua(t[2]) -- ./compiler/lua54.can:640 else -- ./compiler/lua54.can:640 -if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:643 -r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:644 -else -- ./compiler/lua54.can:644 -r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -end -- ./compiler/lua54.can:646 -return r -- ./compiler/lua54.can:649 -end, -- ./compiler/lua54.can:649 -["Paren"] = function(t) -- ./compiler/lua54.can:652 -return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:653 -end, -- ./compiler/lua54.can:653 -["MethodStub"] = function(t) -- ./compiler/lua54.can:656 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:662 -end, -- ./compiler/lua54.can:662 -["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:665 -return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:672 -end, -- ./compiler/lua54.can:672 -["LetExpr"] = function(t) -- ./compiler/lua54.can:679 -return lua(t[1][1]) -- ./compiler/lua54.can:680 -end, -- ./compiler/lua54.can:680 -["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:684 -local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:685 -local r = "(function()" .. indent() -- ./compiler/lua54.can:686 -if hasPush then -- ./compiler/lua54.can:687 -r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:688 -else -- ./compiler/lua54.can:688 -push("push", false) -- ./compiler/lua54.can:690 -end -- ./compiler/lua54.can:690 -r = r .. (lua(t, stat)) -- ./compiler/lua54.can:692 -if hasPush then -- ./compiler/lua54.can:693 -r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:694 -end -- ./compiler/lua54.can:694 -pop("push") -- ./compiler/lua54.can:696 -r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:697 -return r -- ./compiler/lua54.can:698 -end, -- ./compiler/lua54.can:698 -["DoExpr"] = function(t) -- ./compiler/lua54.can:701 -if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:702 -t[# t]["tag"] = "Return" -- ./compiler/lua54.can:703 -end -- ./compiler/lua54.can:703 -return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:705 -end, -- ./compiler/lua54.can:705 -["WhileExpr"] = function(t) -- ./compiler/lua54.can:708 -return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:709 -end, -- ./compiler/lua54.can:709 -["RepeatExpr"] = function(t) -- ./compiler/lua54.can:712 -return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:713 -end, -- ./compiler/lua54.can:713 -["IfExpr"] = function(t) -- ./compiler/lua54.can:716 -for i = 2, # t do -- ./compiler/lua54.can:717 -local block = t[i] -- ./compiler/lua54.can:718 -if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:719 -block[# block]["tag"] = "Return" -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -end -- ./compiler/lua54.can:720 -return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:723 -end, -- ./compiler/lua54.can:723 -["FornumExpr"] = function(t) -- ./compiler/lua54.can:726 -return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:727 -end, -- ./compiler/lua54.can:727 -["ForinExpr"] = function(t) -- ./compiler/lua54.can:730 -return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:731 -end, -- ./compiler/lua54.can:731 -["Call"] = function(t) -- ./compiler/lua54.can:737 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:738 -return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:739 -elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:740 -local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:741 -local replacement = macro["replacement"] -- ./compiler/lua54.can:742 -local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:743 -for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:744 -if arg["tag"] == "Dots" then -- ./compiler/lua54.can:745 -macroargs["..."] = (function() -- ./compiler/lua54.can:746 -local self = {} -- ./compiler/lua54.can:746 -for j = i + 1, # t do -- ./compiler/lua54.can:746 -self[#self+1] = t[j] -- ./compiler/lua54.can:746 -end -- ./compiler/lua54.can:746 -return self -- ./compiler/lua54.can:746 -end)() -- ./compiler/lua54.can:746 -elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:747 -if t[i + 1] == nil then -- ./compiler/lua54.can:748 -error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:749 -end -- ./compiler/lua54.can:749 -macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:751 -else -- ./compiler/lua54.can:751 -error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -end -- ./compiler/lua54.can:753 -push("macroargs", macroargs) -- ./compiler/lua54.can:756 -nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:757 -local r = lua(replacement) -- ./compiler/lua54.can:758 -nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:759 -pop("macroargs") -- ./compiler/lua54.can:760 -return r -- ./compiler/lua54.can:761 -elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:762 -if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:763 -return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:764 -else -- ./compiler/lua54.can:764 -return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:766 -end -- ./compiler/lua54.can:766 -else -- ./compiler/lua54.can:766 -return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:769 +r = tags["_opid"][t[1]](t[2]) -- ./compiler/lua54.can:642 +end -- ./compiler/lua54.can:642 +else -- ./compiler/lua54.can:642 +if type(tags["_opid"][t[1]]) == "string" then -- ./compiler/lua54.can:645 +r = lua(t[2]) .. " " .. tags["_opid"][t[1]] .. " " .. lua(t[3]) -- ./compiler/lua54.can:646 +else -- ./compiler/lua54.can:646 +r = tags["_opid"][t[1]](t[2], t[3]) -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +end -- ./compiler/lua54.can:648 +return r -- ./compiler/lua54.can:651 +end, -- ./compiler/lua54.can:651 +["Paren"] = function(t) -- ./compiler/lua54.can:654 +return "(" .. lua(t[1]) .. ")" -- ./compiler/lua54.can:655 +end, -- ./compiler/lua54.can:655 +["MethodStub"] = function(t) -- ./compiler/lua54.can:658 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:664 +end, -- ./compiler/lua54.can:664 +["SafeMethodStub"] = function(t) -- ./compiler/lua54.can:667 +return "(function()" .. indent() .. "local " .. var("object") .. " = " .. lua(t[1]) .. newline() .. "if " .. var("object") .. " == nil then return nil end" .. newline() .. "local " .. var("method") .. " = " .. var("object") .. "." .. lua(t[2], "Id") .. newline() .. "if " .. var("method") .. " == nil then return nil end" .. newline() .. "return function(...) return " .. var("method") .. "(" .. var("object") .. ", ...) end" .. unindent() .. "end)()" -- ./compiler/lua54.can:674 +end, -- ./compiler/lua54.can:674 +["LetExpr"] = function(t) -- ./compiler/lua54.can:681 +return lua(t[1][1]) -- ./compiler/lua54.can:682 +end, -- ./compiler/lua54.can:682 +["_statexpr"] = function(t, stat) -- ./compiler/lua54.can:686 +local hasPush = any(t, { "Push" }, func) -- ./compiler/lua54.can:687 +local r = "(function()" .. indent() -- ./compiler/lua54.can:688 +if hasPush then -- ./compiler/lua54.can:689 +r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()) -- ./compiler/lua54.can:690 +else -- ./compiler/lua54.can:690 +push("push", false) -- ./compiler/lua54.can:692 +end -- ./compiler/lua54.can:692 +r = r .. (lua(t, stat)) -- ./compiler/lua54.can:694 +if hasPush then -- ./compiler/lua54.can:695 +r = r .. (newline() .. "return " .. UNPACK(var("push"))) -- ./compiler/lua54.can:696 +end -- ./compiler/lua54.can:696 +pop("push") -- ./compiler/lua54.can:698 +r = r .. (unindent() .. "end)()") -- ./compiler/lua54.can:699 +return r -- ./compiler/lua54.can:700 +end, -- ./compiler/lua54.can:700 +["DoExpr"] = function(t) -- ./compiler/lua54.can:703 +if t[# t]["tag"] == "Push" then -- ./compiler/lua54.can:704 +t[# t]["tag"] = "Return" -- ./compiler/lua54.can:705 +end -- ./compiler/lua54.can:705 +return lua(t, "_statexpr", "Do") -- ./compiler/lua54.can:707 +end, -- ./compiler/lua54.can:707 +["WhileExpr"] = function(t) -- ./compiler/lua54.can:710 +return lua(t, "_statexpr", "While") -- ./compiler/lua54.can:711 +end, -- ./compiler/lua54.can:711 +["RepeatExpr"] = function(t) -- ./compiler/lua54.can:714 +return lua(t, "_statexpr", "Repeat") -- ./compiler/lua54.can:715 +end, -- ./compiler/lua54.can:715 +["IfExpr"] = function(t) -- ./compiler/lua54.can:718 +for i = 2, # t do -- ./compiler/lua54.can:719 +local block = t[i] -- ./compiler/lua54.can:720 +if block[# block] and block[# block]["tag"] == "Push" then -- ./compiler/lua54.can:721 +block[# block]["tag"] = "Return" -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +end -- ./compiler/lua54.can:722 +return lua(t, "_statexpr", "If") -- ./compiler/lua54.can:725 +end, -- ./compiler/lua54.can:725 +["FornumExpr"] = function(t) -- ./compiler/lua54.can:728 +return lua(t, "_statexpr", "Fornum") -- ./compiler/lua54.can:729 +end, -- ./compiler/lua54.can:729 +["ForinExpr"] = function(t) -- ./compiler/lua54.can:732 +return lua(t, "_statexpr", "Forin") -- ./compiler/lua54.can:733 +end, -- ./compiler/lua54.can:733 +["Call"] = function(t) -- ./compiler/lua54.can:739 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:740 +return "(" .. lua(t[1]) .. ")(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:741 +elseif t[1]["tag"] == "Id" and not nomacro["functions"][t[1][1]] and macros["functions"][t[1][1]] then -- ./compiler/lua54.can:742 +local macro = macros["functions"][t[1][1]] -- ./compiler/lua54.can:743 +local replacement = macro["replacement"] -- ./compiler/lua54.can:744 +local r -- ./compiler/lua54.can:745 +nomacro["functions"][t[1][1]] = true -- ./compiler/lua54.can:746 +if type(replacement) == "function" then -- ./compiler/lua54.can:747 +local args = {} -- ./compiler/lua54.can:748 +for i = 2, # t do -- ./compiler/lua54.can:749 +table["insert"](args, lua(t[i])) -- ./compiler/lua54.can:750 +end -- ./compiler/lua54.can:750 +r = replacement(unpack(args)) -- ./compiler/lua54.can:752 +else -- ./compiler/lua54.can:752 +local macroargs = util["merge"](peek("macroargs")) -- ./compiler/lua54.can:754 +for i, arg in ipairs(macro["args"]) do -- ./compiler/lua54.can:755 +if arg["tag"] == "Dots" then -- ./compiler/lua54.can:756 +macroargs["..."] = (function() -- ./compiler/lua54.can:757 +local self = {} -- ./compiler/lua54.can:757 +for j = i + 1, # t do -- ./compiler/lua54.can:757 +self[#self+1] = t[j] -- ./compiler/lua54.can:757 +end -- ./compiler/lua54.can:757 +return self -- ./compiler/lua54.can:757 +end)() -- ./compiler/lua54.can:757 +elseif arg["tag"] == "Id" then -- ./compiler/lua54.can:758 +if t[i + 1] == nil then -- ./compiler/lua54.can:759 +error(("bad argument #%s to macro %s (value expected)"):format(i, t[1][1])) -- ./compiler/lua54.can:760 +end -- ./compiler/lua54.can:760 +macroargs[arg[1]] = t[i + 1] -- ./compiler/lua54.can:762 +else -- ./compiler/lua54.can:762 +error(("unexpected argument type %s in macro %s"):format(arg["tag"], t[1][1])) -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +end -- ./compiler/lua54.can:764 +push("macroargs", macroargs) -- ./compiler/lua54.can:767 +r = lua(replacement) -- ./compiler/lua54.can:768 +pop("macroargs") -- ./compiler/lua54.can:769 end -- ./compiler/lua54.can:769 -end, -- ./compiler/lua54.can:769 -["SafeCall"] = function(t) -- ./compiler/lua54.can:773 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:774 -return lua(t, "SafeIndex") -- ./compiler/lua54.can:775 +nomacro["functions"][t[1][1]] = nil -- ./compiler/lua54.can:771 +return r -- ./compiler/lua54.can:772 +elseif t[1]["tag"] == "MethodStub" then -- ./compiler/lua54.can:773 +if t[1][1]["tag"] == "String" or t[1][1]["tag"] == "Table" then -- ./compiler/lua54.can:774 +return "(" .. lua(t[1][1]) .. "):" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:775 else -- ./compiler/lua54.can:775 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:777 +return lua(t[1][1]) .. ":" .. lua(t[1][2], "Id") .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:777 end -- ./compiler/lua54.can:777 -end, -- ./compiler/lua54.can:777 -["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:782 -if start == nil then start = 1 end -- ./compiler/lua54.can:782 -local r -- ./compiler/lua54.can:783 -if t[start] then -- ./compiler/lua54.can:784 -r = lua(t[start]) -- ./compiler/lua54.can:785 -for i = start + 1, # t, 1 do -- ./compiler/lua54.can:786 -r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:787 -end -- ./compiler/lua54.can:787 -else -- ./compiler/lua54.can:787 -r = "" -- ./compiler/lua54.can:790 -end -- ./compiler/lua54.can:790 -return r -- ./compiler/lua54.can:792 -end, -- ./compiler/lua54.can:792 -["Id"] = function(t) -- ./compiler/lua54.can:795 -local macroargs = peek("macroargs") -- ./compiler/lua54.can:796 -if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:797 -if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:798 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:799 -local r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:800 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:801 -return r -- ./compiler/lua54.can:802 -elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:803 -nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:804 -local r = lua(macros["variables"][t[1]]) -- ./compiler/lua54.can:805 -nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:806 -return r -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -end -- ./compiler/lua54.can:807 -return t[1] -- ./compiler/lua54.can:810 -end, -- ./compiler/lua54.can:810 -["AttributeId"] = function(t) -- ./compiler/lua54.can:813 -if t[2] then -- ./compiler/lua54.can:814 -return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:815 -else -- ./compiler/lua54.can:815 -return t[1] -- ./compiler/lua54.can:817 -end -- ./compiler/lua54.can:817 -end, -- ./compiler/lua54.can:817 -["DestructuringId"] = function(t) -- ./compiler/lua54.can:821 -if t["id"] then -- ./compiler/lua54.can:822 -return t["id"] -- ./compiler/lua54.can:823 -else -- ./compiler/lua54.can:823 -local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:825 -local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:826 -for j = 1, # t, 1 do -- ./compiler/lua54.can:827 -table["insert"](vars, t[j]) -- ./compiler/lua54.can:828 -end -- ./compiler/lua54.can:828 -table["insert"](d, vars) -- ./compiler/lua54.can:830 -t["id"] = vars["id"] -- ./compiler/lua54.can:831 -return vars["id"] -- ./compiler/lua54.can:832 -end -- ./compiler/lua54.can:832 -end, -- ./compiler/lua54.can:832 -["Index"] = function(t) -- ./compiler/lua54.can:836 -if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:837 -return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:838 -else -- ./compiler/lua54.can:838 -return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:840 -end -- ./compiler/lua54.can:840 -end, -- ./compiler/lua54.can:840 -["SafeIndex"] = function(t) -- ./compiler/lua54.can:844 -if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:845 -local l = {} -- ./compiler/lua54.can:846 -while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:847 -table["insert"](l, 1, t) -- ./compiler/lua54.can:848 -t = t[1] -- ./compiler/lua54.can:849 -end -- ./compiler/lua54.can:849 -local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:851 -for _, e in ipairs(l) do -- ./compiler/lua54.can:852 -r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:853 -if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:854 -r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:855 -else -- ./compiler/lua54.can:855 -r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -end -- ./compiler/lua54.can:857 -r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:860 -return r -- ./compiler/lua54.can:861 -else -- ./compiler/lua54.can:861 -return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:863 -end -- ./compiler/lua54.can:863 -end, -- ./compiler/lua54.can:863 -["_opid"] = { -- ./compiler/lua54.can:868 -["add"] = "+", -- ./compiler/lua54.can:869 -["sub"] = "-", -- ./compiler/lua54.can:869 -["mul"] = "*", -- ./compiler/lua54.can:869 -["div"] = "/", -- ./compiler/lua54.can:869 -["idiv"] = "//", -- ./compiler/lua54.can:870 -["mod"] = "%", -- ./compiler/lua54.can:870 -["pow"] = "^", -- ./compiler/lua54.can:870 -["concat"] = "..", -- ./compiler/lua54.can:870 -["band"] = "&", -- ./compiler/lua54.can:871 -["bor"] = "|", -- ./compiler/lua54.can:871 -["bxor"] = "~", -- ./compiler/lua54.can:871 -["shl"] = "<<", -- ./compiler/lua54.can:871 -["shr"] = ">>", -- ./compiler/lua54.can:871 -["eq"] = "==", -- ./compiler/lua54.can:872 -["ne"] = "~=", -- ./compiler/lua54.can:872 -["lt"] = "<", -- ./compiler/lua54.can:872 -["gt"] = ">", -- ./compiler/lua54.can:872 -["le"] = "<=", -- ./compiler/lua54.can:872 -["ge"] = ">=", -- ./compiler/lua54.can:872 -["and"] = "and", -- ./compiler/lua54.can:873 -["or"] = "or", -- ./compiler/lua54.can:873 -["unm"] = "-", -- ./compiler/lua54.can:873 -["len"] = "#", -- ./compiler/lua54.can:873 -["bnot"] = "~", -- ./compiler/lua54.can:873 -["not"] = "not" -- ./compiler/lua54.can:873 -} -- ./compiler/lua54.can:873 -}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:876 -error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:877 -end }) -- ./compiler/lua54.can:877 +else -- ./compiler/lua54.can:777 +return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")" -- ./compiler/lua54.can:780 +end -- ./compiler/lua54.can:780 +end, -- ./compiler/lua54.can:780 +["SafeCall"] = function(t) -- ./compiler/lua54.can:784 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:785 +return lua(t, "SafeIndex") -- ./compiler/lua54.can:786 +else -- ./compiler/lua54.can:786 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ") or nil)" -- ./compiler/lua54.can:788 +end -- ./compiler/lua54.can:788 +end, -- ./compiler/lua54.can:788 +["_lhs"] = function(t, start, newlines) -- ./compiler/lua54.can:793 +if start == nil then start = 1 end -- ./compiler/lua54.can:793 +local r -- ./compiler/lua54.can:794 +if t[start] then -- ./compiler/lua54.can:795 +r = lua(t[start]) -- ./compiler/lua54.can:796 +for i = start + 1, # t, 1 do -- ./compiler/lua54.can:797 +r = r .. ("," .. (newlines and newline() or " ") .. lua(t[i])) -- ./compiler/lua54.can:798 +end -- ./compiler/lua54.can:798 +else -- ./compiler/lua54.can:798 +r = "" -- ./compiler/lua54.can:801 +end -- ./compiler/lua54.can:801 +return r -- ./compiler/lua54.can:803 +end, -- ./compiler/lua54.can:803 +["Id"] = function(t) -- ./compiler/lua54.can:806 +local r = t[1] -- ./compiler/lua54.can:807 +local macroargs = peek("macroargs") -- ./compiler/lua54.can:808 +if not nomacro["variables"][t[1]] then -- ./compiler/lua54.can:809 +nomacro["variables"][t[1]] = true -- ./compiler/lua54.can:810 +if macroargs and macroargs[t[1]] then -- ./compiler/lua54.can:811 +r = lua(macroargs[t[1]]) -- ./compiler/lua54.can:812 +elseif macros["variables"][t[1]] ~= nil then -- ./compiler/lua54.can:813 +local macro = macros["variables"][t[1]] -- ./compiler/lua54.can:814 +if type(macro) == "function" then -- ./compiler/lua54.can:815 +r = macro() -- ./compiler/lua54.can:816 +else -- ./compiler/lua54.can:816 +r = lua(macro) -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +end -- ./compiler/lua54.can:818 +nomacro["variables"][t[1]] = nil -- ./compiler/lua54.can:821 +end -- ./compiler/lua54.can:821 +return r -- ./compiler/lua54.can:823 +end, -- ./compiler/lua54.can:823 +["AttributeId"] = function(t) -- ./compiler/lua54.can:826 +if t[2] then -- ./compiler/lua54.can:827 +return t[1] .. " <" .. t[2] .. ">" -- ./compiler/lua54.can:828 +else -- ./compiler/lua54.can:828 +return t[1] -- ./compiler/lua54.can:830 +end -- ./compiler/lua54.can:830 +end, -- ./compiler/lua54.can:830 +["DestructuringId"] = function(t) -- ./compiler/lua54.can:834 +if t["id"] then -- ./compiler/lua54.can:835 +return t["id"] -- ./compiler/lua54.can:836 +else -- ./compiler/lua54.can:836 +local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") -- ./compiler/lua54.can:838 +local vars = { ["id"] = tmp() } -- ./compiler/lua54.can:839 +for j = 1, # t, 1 do -- ./compiler/lua54.can:840 +table["insert"](vars, t[j]) -- ./compiler/lua54.can:841 +end -- ./compiler/lua54.can:841 +table["insert"](d, vars) -- ./compiler/lua54.can:843 +t["id"] = vars["id"] -- ./compiler/lua54.can:844 +return vars["id"] -- ./compiler/lua54.can:845 +end -- ./compiler/lua54.can:845 +end, -- ./compiler/lua54.can:845 +["Index"] = function(t) -- ./compiler/lua54.can:849 +if t[1]["tag"] == "String" or t[1]["tag"] == "Table" then -- ./compiler/lua54.can:850 +return "(" .. lua(t[1]) .. ")[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:851 +else -- ./compiler/lua54.can:851 +return lua(t[1]) .. "[" .. lua(t[2]) .. "]" -- ./compiler/lua54.can:853 +end -- ./compiler/lua54.can:853 +end, -- ./compiler/lua54.can:853 +["SafeIndex"] = function(t) -- ./compiler/lua54.can:857 +if t[1]["tag"] ~= "Id" then -- ./compiler/lua54.can:858 +local l = {} -- ./compiler/lua54.can:859 +while t["tag"] == "SafeIndex" or t["tag"] == "SafeCall" do -- ./compiler/lua54.can:860 +table["insert"](l, 1, t) -- ./compiler/lua54.can:861 +t = t[1] -- ./compiler/lua54.can:862 +end -- ./compiler/lua54.can:862 +local r = "(function()" .. indent() .. "local " .. var("safe") .. " = " .. lua(l[1][1]) .. newline() -- ./compiler/lua54.can:864 +for _, e in ipairs(l) do -- ./compiler/lua54.can:865 +r = r .. ("if " .. var("safe") .. " == nil then return nil end" .. newline()) -- ./compiler/lua54.can:866 +if e["tag"] == "SafeIndex" then -- ./compiler/lua54.can:867 +r = r .. (var("safe") .. " = " .. var("safe") .. "[" .. lua(e[2]) .. "]" .. newline()) -- ./compiler/lua54.can:868 +else -- ./compiler/lua54.can:868 +r = r .. (var("safe") .. " = " .. var("safe") .. "(" .. lua(e, "_lhs", 2) .. ")" .. newline()) -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +end -- ./compiler/lua54.can:870 +r = r .. ("return " .. var("safe") .. unindent() .. "end)()") -- ./compiler/lua54.can:873 +return r -- ./compiler/lua54.can:874 +else -- ./compiler/lua54.can:874 +return "(" .. lua(t[1]) .. " ~= nil and " .. lua(t[1]) .. "[" .. lua(t[2]) .. "] or nil)" -- ./compiler/lua54.can:876 +end -- ./compiler/lua54.can:876 +end, -- ./compiler/lua54.can:876 +["_opid"] = { -- ./compiler/lua54.can:881 +["add"] = "+", -- ./compiler/lua54.can:882 +["sub"] = "-", -- ./compiler/lua54.can:882 +["mul"] = "*", -- ./compiler/lua54.can:882 +["div"] = "/", -- ./compiler/lua54.can:882 +["idiv"] = "//", -- ./compiler/lua54.can:883 +["mod"] = "%", -- ./compiler/lua54.can:883 +["pow"] = "^", -- ./compiler/lua54.can:883 +["concat"] = "..", -- ./compiler/lua54.can:883 +["band"] = "&", -- ./compiler/lua54.can:884 +["bor"] = "|", -- ./compiler/lua54.can:884 +["bxor"] = "~", -- ./compiler/lua54.can:884 +["shl"] = "<<", -- ./compiler/lua54.can:884 +["shr"] = ">>", -- ./compiler/lua54.can:884 +["eq"] = "==", -- ./compiler/lua54.can:885 +["ne"] = "~=", -- ./compiler/lua54.can:885 +["lt"] = "<", -- ./compiler/lua54.can:885 +["gt"] = ">", -- ./compiler/lua54.can:885 +["le"] = "<=", -- ./compiler/lua54.can:885 +["ge"] = ">=", -- ./compiler/lua54.can:885 +["and"] = "and", -- ./compiler/lua54.can:886 +["or"] = "or", -- ./compiler/lua54.can:886 +["unm"] = "-", -- ./compiler/lua54.can:886 +["len"] = "#", -- ./compiler/lua54.can:886 +["bnot"] = "~", -- ./compiler/lua54.can:886 +["not"] = "not" -- ./compiler/lua54.can:886 +} -- ./compiler/lua54.can:886 +}, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 +error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 +end }) -- ./compiler/lua54.can:890 targetName = "Lua 5.3" -- ./compiler/lua53.can:1 tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 if t[2] then -- ./compiler/lua53.can:5 @@ -4961,11 +5021,11 @@ end -- ./compiler/lua51.can:26 tags["Label"] = function() -- ./compiler/lua51.can:28 error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 end -- ./compiler/lua51.can:29 -local code = lua(ast) .. newline() -- ./compiler/lua54.can:883 -return requireStr .. code -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -end -- ./compiler/lua54.can:884 -local lua54 = _() or lua54 -- ./compiler/lua54.can:889 +local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 +return requireStr .. code -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +end -- ./compiler/lua54.can:897 +local lua54 = _() or lua54 -- ./compiler/lua54.can:902 return lua54 -- ./compiler/lua53.can:18 end -- ./compiler/lua53.can:18 local lua53 = _() or lua53 -- ./compiler/lua53.can:22 @@ -6851,192 +6911,197 @@ end -- candran.can:146 env["define"] = function(identifier, replacement) -- candran.can:149 local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:151 if not iast then -- candran.can:152 -return error(("in macro identifier: %s"):format(ierr)) -- candran.can:153 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:153 end -- candran.can:153 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:156 -if not rast then -- candran.can:157 -return error(("in macro replacement: %s"):format(rerr)) -- candran.can:158 -end -- candran.can:158 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:161 -rast = rast[1][1] -- candran.can:162 -end -- candran.can:162 -if iast["tag"] == "MacroFunction" then -- candran.can:165 -macros["functions"][iast[1][1]] = { -- candran.can:166 -["args"] = iast[2], -- candran.can:166 -["replacement"] = rast -- candran.can:166 -} -- candran.can:166 -elseif iast["tag"] == "Id" then -- candran.can:167 -macros["variables"][iast[1]] = rast -- candran.can:168 -else -- candran.can:168 -error(("invalid macro type %s"):format(iast["tag"])) -- candran.can:170 -end -- candran.can:170 -end -- candran.can:170 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:175 -if not preprocess then -- candran.can:176 -return nil, "in preprocessor: " .. err -- candran.can:177 -end -- candran.can:177 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:180 +if type(replacement) == "string" then -- candran.can:156 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:157 +if not rast then -- candran.can:158 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:159 +end -- candran.can:159 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:162 +rast = rast[1][1] -- candran.can:163 +end -- candran.can:163 +replacement = rast -- candran.can:165 +elseif type(replacement) ~= "function" then -- candran.can:166 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:167 +end -- candran.can:167 +if iast["tag"] == "MacroFunction" then -- candran.can:170 +macros["functions"][iast[1][1]] = { -- candran.can:171 +["args"] = iast[2], -- candran.can:171 +["replacement"] = replacement -- candran.can:171 +} -- candran.can:171 +elseif iast["tag"] == "Id" then -- candran.can:172 +macros["variables"][iast[1]] = replacement -- candran.can:173 +else -- candran.can:173 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:175 +end -- candran.can:175 +end -- candran.can:175 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:180 if not preprocess then -- candran.can:181 return nil, "in preprocessor: " .. err -- candran.can:182 end -- candran.can:182 -local success, output = pcall(preprocess) -- candran.can:186 -if not success then -- candran.can:187 -return nil, "in preprocessor: " .. output -- candran.can:188 -end -- candran.can:188 -return output, macros -- candran.can:191 -end -- candran.can:191 -candran["compile"] = function(input, options, macros) -- candran.can:201 -if options == nil then options = {} end -- candran.can:201 -options = util["merge"](candran["default"], options) -- candran.can:202 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:204 -if not ast then -- candran.can:206 -return nil, errmsg -- candran.can:207 -end -- candran.can:207 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:210 -end -- candran.can:210 -candran["make"] = function(code, options) -- candran.can:219 -local r, err = candran["preprocess"](code, options) -- candran.can:220 -if r then -- candran.can:221 -r, err = candran["compile"](r, options, err) -- candran.can:222 -if r then -- candran.can:223 -return r -- candran.can:224 -end -- candran.can:224 -end -- candran.can:224 -return r, err -- candran.can:227 -end -- candran.can:227 -local errorRewritingActive = false -- candran.can:230 -local codeCache = {} -- candran.can:231 -candran["loadfile"] = function(filepath, env, options) -- candran.can:234 -local f, err = io["open"](filepath) -- candran.can:235 -if not f then -- candran.can:236 -return nil, ("cannot open %s"):format(err) -- candran.can:237 -end -- candran.can:237 -local content = f:read("*a") -- candran.can:239 -f:close() -- candran.can:240 -return candran["load"](content, filepath, env, options) -- candran.can:242 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:185 +if not preprocess then -- candran.can:186 +return nil, "in preprocessor: " .. err -- candran.can:187 +end -- candran.can:187 +local success, output = pcall(preprocess) -- candran.can:191 +if not success then -- candran.can:192 +return nil, "in preprocessor: " .. output -- candran.can:193 +end -- candran.can:193 +return output, macros -- candran.can:196 +end -- candran.can:196 +candran["compile"] = function(input, options, macros) -- candran.can:206 +if options == nil then options = {} end -- candran.can:206 +options = util["merge"](candran["default"], options) -- candran.can:207 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:209 +if not ast then -- candran.can:211 +return nil, errmsg -- candran.can:212 +end -- candran.can:212 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:215 +end -- candran.can:215 +candran["make"] = function(code, options) -- candran.can:224 +local r, err = candran["preprocess"](code, options) -- candran.can:225 +if r then -- candran.can:226 +r, err = candran["compile"](r, options, err) -- candran.can:227 +if r then -- candran.can:228 +return r -- candran.can:229 +end -- candran.can:229 +end -- candran.can:229 +return r, err -- candran.can:232 +end -- candran.can:232 +local errorRewritingActive = false -- candran.can:235 +local codeCache = {} -- candran.can:236 +candran["loadfile"] = function(filepath, env, options) -- candran.can:239 +local f, err = io["open"](filepath) -- candran.can:240 +if not f then -- candran.can:241 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:242 end -- candran.can:242 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:247 -if options == nil then options = {} end -- candran.can:247 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:248 -local code, err = candran["make"](chunk, options) -- candran.can:250 -if not code then -- candran.can:251 -return code, err -- candran.can:252 -end -- candran.can:252 -codeCache[options["chunkname"]] = code -- candran.can:255 -local f -- candran.can:256 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:257 -if f == nil then -- candran.can:262 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:263 -end -- candran.can:263 -if options["rewriteErrors"] == false then -- candran.can:266 -return f -- candran.can:267 -else -- candran.can:267 -return function(...) -- candran.can:269 -if not errorRewritingActive then -- candran.can:270 -errorRewritingActive = true -- candran.can:271 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:272 -errorRewritingActive = false -- candran.can:273 -if t[1] == false then -- candran.can:274 -error(t[2], 0) -- candran.can:275 -end -- candran.can:275 -return unpack(t, 2) -- candran.can:277 -else -- candran.can:277 -return f(...) -- candran.can:279 -end -- candran.can:279 -end -- candran.can:279 -end -- candran.can:279 -end -- candran.can:279 -candran["dofile"] = function(filename, options) -- candran.can:287 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:288 -if f == nil then -- candran.can:290 -error(err) -- candran.can:291 -else -- candran.can:291 -return f() -- candran.can:293 -end -- candran.can:293 -end -- candran.can:293 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:299 +local content = f:read("*a") -- candran.can:244 +f:close() -- candran.can:245 +return candran["load"](content, filepath, env, options) -- candran.can:247 +end -- candran.can:247 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:252 +if options == nil then options = {} end -- candran.can:252 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:253 +local code, err = candran["make"](chunk, options) -- candran.can:255 +if not code then -- candran.can:256 +return code, err -- candran.can:257 +end -- candran.can:257 +codeCache[options["chunkname"]] = code -- candran.can:260 +local f -- candran.can:261 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:262 +if f == nil then -- candran.can:267 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:268 +end -- candran.can:268 +if options["rewriteErrors"] == false then -- candran.can:271 +return f -- candran.can:272 +else -- candran.can:272 +return function(...) -- candran.can:274 +if not errorRewritingActive then -- candran.can:275 +errorRewritingActive = true -- candran.can:276 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:277 +errorRewritingActive = false -- candran.can:278 +if t[1] == false then -- candran.can:279 +error(t[2], 0) -- candran.can:280 +end -- candran.can:280 +return unpack(t, 2) -- candran.can:282 +else -- candran.can:282 +return f(...) -- candran.can:284 +end -- candran.can:284 +end -- candran.can:284 +end -- candran.can:284 +end -- candran.can:284 +candran["dofile"] = function(filename, options) -- candran.can:292 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:293 +if f == nil then -- candran.can:295 +error(err) -- candran.can:296 +else -- candran.can:296 +return f() -- candran.can:298 +end -- candran.can:298 +end -- candran.can:298 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:304 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:300 -message = debug["traceback"](message, 2) -- candran.can:301 -end -- candran.can:301 +") then -- candran.can:305 +message = debug["traceback"](message, 2) -- candran.can:306 +end -- candran.can:306 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:303 -line = tonumber(line) -- candran.can:304 -local originalFile -- candran.can:306 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:307 -if strName then -- candran.can:308 -if codeCache[strName] then -- candran.can:309 -originalFile = codeCache[strName] -- candran.can:310 -source = strName -- candran.can:311 -end -- candran.can:311 -else -- candran.can:311 -do -- candran.can:314 -local fi -- candran.can:314 -fi = io["open"](source, "r") -- candran.can:314 -if fi then -- candran.can:314 -originalFile = fi:read("*a") -- candran.can:315 -fi:close() -- candran.can:316 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:308 +line = tonumber(line) -- candran.can:309 +local originalFile -- candran.can:311 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:312 +if strName then -- candran.can:313 +if codeCache[strName] then -- candran.can:314 +originalFile = codeCache[strName] -- candran.can:315 +source = strName -- candran.can:316 end -- candran.can:316 -end -- candran.can:316 -end -- candran.can:316 -if originalFile then -- candran.can:320 -local i = 0 -- candran.can:321 +else -- candran.can:316 +do -- candran.can:319 +local fi -- candran.can:319 +fi = io["open"](source, "r") -- candran.can:319 +if fi then -- candran.can:319 +originalFile = fi:read("*a") -- candran.can:320 +fi:close() -- candran.can:321 +end -- candran.can:321 +end -- candran.can:321 +end -- candran.can:321 +if originalFile then -- candran.can:325 +local i = 0 -- candran.can:326 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:322 -i = i + 1 -- candran.can:323 -if i == line then -- candran.can:324 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:325 -if lineMap then -- candran.can:326 -if extSource ~= source then -- candran.can:327 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:328 -else -- candran.can:328 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:330 -end -- candran.can:330 -end -- candran.can:330 -break -- candran.can:333 -end -- candran.can:333 -end -- candran.can:333 -end -- candran.can:333 -end) -- candran.can:333 -end -- candran.can:333 -candran["searcher"] = function(modpath) -- candran.can:341 -local filepath = util["search"](modpath, { "can" }) -- candran.can:342 -if not filepath then -- candran.can:343 -if _VERSION == "Lua 5.4" then -- candran.can:344 -return "no candran file in package.path" -- candran.can:345 -else -- candran.can:345 +") do -- candran.can:327 +i = i + 1 -- candran.can:328 +if i == line then -- candran.can:329 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:330 +if lineMap then -- candran.can:331 +if extSource ~= source then -- candran.can:332 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:333 +else -- candran.can:333 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:335 +end -- candran.can:335 +end -- candran.can:335 +break -- candran.can:338 +end -- candran.can:338 +end -- candran.can:338 +end -- candran.can:338 +end) -- candran.can:338 +end -- candran.can:338 +candran["searcher"] = function(modpath) -- candran.can:346 +local filepath = util["search"](modpath, { "can" }) -- candran.can:347 +if not filepath then -- candran.can:348 +if _VERSION == "Lua 5.4" then -- candran.can:349 +return "no candran file in package.path" -- candran.can:350 +else -- candran.can:350 return "\ -\9no candran file in package.path" -- candran.can:347 -end -- candran.can:347 -end -- candran.can:347 -return function(modpath) -- candran.can:350 -local r, s = candran["loadfile"](filepath) -- candran.can:351 -if r then -- candran.can:352 -return r(modpath, filepath) -- candran.can:353 -else -- candran.can:353 +\9no candran file in package.path" -- candran.can:352 +end -- candran.can:352 +end -- candran.can:352 +return function(modpath) -- candran.can:355 +local r, s = candran["loadfile"](filepath) -- candran.can:356 +if r then -- candran.can:357 +return r(modpath, filepath) -- candran.can:358 +else -- candran.can:358 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, s), 0) -- candran.can:355 -end -- candran.can:355 -end, filepath -- candran.can:357 -end -- candran.can:357 -candran["setup"] = function() -- candran.can:361 -local searchers = (function() -- candran.can:362 -if _VERSION == "Lua 5.1" then -- candran.can:362 -return package["loaders"] -- candran.can:363 -else -- candran.can:363 -return package["searchers"] -- candran.can:365 -end -- candran.can:365 -end)() -- candran.can:365 -for _, s in ipairs(searchers) do -- candran.can:368 -if s == candran["searcher"] then -- candran.can:369 -return candran -- candran.can:370 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:360 +end -- candran.can:360 +end, filepath -- candran.can:362 +end -- candran.can:362 +candran["setup"] = function() -- candran.can:366 +local searchers = (function() -- candran.can:367 +if _VERSION == "Lua 5.1" then -- candran.can:367 +return package["loaders"] -- candran.can:368 +else -- candran.can:368 +return package["searchers"] -- candran.can:370 end -- candran.can:370 -end -- candran.can:370 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:374 +end)() -- candran.can:370 +for _, s in ipairs(searchers) do -- candran.can:373 +if s == candran["searcher"] then -- candran.can:374 return candran -- candran.can:375 end -- candran.can:375 -return candran -- candran.can:378 +end -- candran.can:375 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:379 +return candran -- candran.can:380 +end -- candran.can:380 +return candran -- candran.can:383 diff --git a/compiler/lua54.can b/compiler/lua54.can index f8a3df8..49bf3a1 100644 --- a/compiler/lua54.can +++ b/compiler/lua54.can @@ -2,6 +2,8 @@ local util = require("candran.util") local targetName = "Lua 5.4" +local unpack = unpack or table.unpack + return function(code, ast, options, macros={functions={}, variables={}}) --- Line mapping local lastInputPos = 1 -- last token position in the input code @@ -740,24 +742,33 @@ return function(code, ast, options, macros={functions={}, variables={}}) elseif t[1].tag == "Id" and not nomacro.functions[t[1][1]] and macros.functions[t[1][1]] then local macro = macros.functions[t[1][1]] local replacement = macro.replacement - local macroargs = util.merge(peek("macroargs")) - for i, arg in ipairs(macro.args) do - if arg.tag == "Dots" then - macroargs["..."] = [for j=i+1, #t do t[j] end] - elseif arg.tag == "Id" then - if t[i+1] == nil then - error("bad argument #%s to macro %s (value expected)":format(i, t[1][1])) - end - macroargs[arg[1]] = t[i+1] - else - error("unexpected argument type %s in macro %s":format(arg.tag, t[1][1])) - end - end - push("macroargs", macroargs) + local r nomacro.functions[t[1][1]] = true - local r = lua(replacement) + if type(replacement) == "function" then + local args = {} + for i=2, #t do + table.insert(args, lua(t[i])) + end + r = replacement(unpack(args)) + else + local macroargs = util.merge(peek("macroargs")) + for i, arg in ipairs(macro.args) do + if arg.tag == "Dots" then + macroargs["..."] = [for j=i+1, #t do t[j] end] + elseif arg.tag == "Id" then + if t[i+1] == nil then + error("bad argument #%s to macro %s (value expected)":format(i, t[1][1])) + end + macroargs[arg[1]] = t[i+1] + else + error("unexpected argument type %s in macro %s":format(arg.tag, t[1][1])) + end + end + push("macroargs", macroargs) + r = lua(replacement) + pop("macroargs") + end nomacro.functions[t[1][1]] = nil - pop("macroargs") return r elseif t[1].tag == "MethodStub" then -- method call if t[1][1].tag == "String" or t[1][1].tag == "Table" then @@ -793,21 +804,23 @@ return function(code, ast, options, macros={functions={}, variables={}}) end, -- Id{ } Id = (t) + local r = t[1] local macroargs = peek("macroargs") if not nomacro.variables[t[1]] then + nomacro.variables[t[1]] = true if macroargs and macroargs[t[1]] then -- replace with macro argument - nomacro.variables[t[1]] = true - local r = lua(macroargs[t[1]]) - nomacro.variables[t[1]] = nil - return r + r = lua(macroargs[t[1]]) elseif macros.variables[t[1]] ~= nil then -- replace with macro variable - nomacro.variables[t[1]] = true - local r = lua(macros.variables[t[1]]) - nomacro.variables[t[1]] = nil - return r + local macro = macros.variables[t[1]] + if type(macro) == "function" then + r = macro() + else + r = lua(macro) + end end + nomacro.variables[t[1]] = nil end - return t[1] + return r end, -- AttributeId{ ? } AttributeId = (t) diff --git a/test/test.lua b/test/test.lua index 0a5f635..531df53 100644 --- a/test/test.lua +++ b/test/test.lua @@ -199,6 +199,17 @@ x = f(x) return x ]], 42) +test("preprocessor macro replace variable with function", [[ +#define("a", function() return "42" end) +return a +]], 42) + +test("preprocessor macro replace function with function", [[ +#define("test(x)", function(x) return ("%s = 42"):format(x) end) +test(hello) +return hello +]], 42) + ---------------------- -- SYNTAX ADDITIONS -- ---------------------- From ea54376aa6a03ed136684b45c00d17c9d041f7be Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 11 Jun 2021 14:17:55 +0200 Subject: [PATCH 37/52] Add constexpr and __STR__ default macros --- candran.can | 9 + candran.lua | 851 +++++++++++++++++++++++++++++--------------- candran/serpent.lua | 163 +++++++++ 3 files changed, 736 insertions(+), 287 deletions(-) create mode 100644 candran/serpent.lua diff --git a/candran.can b/candran.can index cdb0ab7..cf1a7ce 100644 --- a/candran.can +++ b/candran.can @@ -1,5 +1,6 @@ #import("candran.util") #import("candran.cmdline") +#import("candran.serpent") #import("compiler.lua54") #import("compiler.lua53") @@ -176,6 +177,14 @@ function candran.preprocess(input, options={}) end end + -- default macros + -- TODO make it optional + env.define("__STR__(x)", function(x) return ("%q"):format(x) end) + local s = require("candran.serpent") + env.define("constexpr(expr)", function(expr) + return s.block(assert(candran.load(expr))(), {fatal = true}) + end) + -- compile & load preprocessor local preprocess, err = candran.compile(preprocessor, options) if not preprocess then diff --git a/candran.lua b/candran.lua index 6148a8f..eb17932 100644 --- a/candran.lua +++ b/candran.lua @@ -141,7 +141,277 @@ end -- ./candran/cmdline.lua:125 end -- ./candran/cmdline.lua:125 local cmdline = _() or cmdline -- ./candran/cmdline.lua:130 package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua:131 -local function _() -- ./candran/cmdline.lua:135 +local function _() -- ./candran/cmdline.lua:134 +local n, v = "serpent", "0.302" -- ./candran/serpent.lua:24 +local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" -- ./candran/serpent.lua:25 +local snum = { -- ./candran/serpent.lua:26 +[tostring(1 / 0)] = "1/0 --[[math.huge]]", -- ./candran/serpent.lua:26 +[tostring(- 1 / 0)] = "-1/0 --[[-math.huge]]", -- ./candran/serpent.lua:26 +[tostring(0 / 0)] = "0/0" -- ./candran/serpent.lua:26 +} -- ./candran/serpent.lua:26 +local badtype = { -- ./candran/serpent.lua:27 +["thread"] = true, -- ./candran/serpent.lua:27 +["userdata"] = true, -- ./candran/serpent.lua:27 +["cdata"] = true -- ./candran/serpent.lua:27 +} -- ./candran/serpent.lua:27 +local getmetatable = debug and debug["getmetatable"] or getmetatable -- ./candran/serpent.lua:28 +local pairs = function(t) -- ./candran/serpent.lua:29 +return next, t -- ./candran/serpent.lua:29 +end -- ./candran/serpent.lua:29 +local keyword, globals, G = {}, {}, (_G or _ENV) -- ./candran/serpent.lua:30 +for _, k in ipairs({ -- ./candran/serpent.lua:31 +"and", -- ./candran/serpent.lua:31 +"break", -- ./candran/serpent.lua:31 +"do", -- ./candran/serpent.lua:31 +"else", -- ./candran/serpent.lua:31 +"elseif", -- ./candran/serpent.lua:31 +"end", -- ./candran/serpent.lua:31 +"false", -- ./candran/serpent.lua:31 +"for", -- ./candran/serpent.lua:32 +"function", -- ./candran/serpent.lua:32 +"goto", -- ./candran/serpent.lua:32 +"if", -- ./candran/serpent.lua:32 +"in", -- ./candran/serpent.lua:32 +"local", -- ./candran/serpent.lua:32 +"nil", -- ./candran/serpent.lua:32 +"not", -- ./candran/serpent.lua:32 +"or", -- ./candran/serpent.lua:32 +"repeat", -- ./candran/serpent.lua:32 +"return", -- ./candran/serpent.lua:33 +"then", -- ./candran/serpent.lua:33 +"true", -- ./candran/serpent.lua:33 +"until", -- ./candran/serpent.lua:33 +"while" -- ./candran/serpent.lua:33 +}) do -- ./candran/serpent.lua:33 +keyword[k] = true -- ./candran/serpent.lua:33 +end -- ./candran/serpent.lua:33 +for k, v in pairs(G) do -- ./candran/serpent.lua:34 +globals[v] = k -- ./candran/serpent.lua:34 +end -- ./candran/serpent.lua:34 +for _, g in ipairs({ -- ./candran/serpent.lua:35 +"coroutine", -- ./candran/serpent.lua:35 +"debug", -- ./candran/serpent.lua:35 +"io", -- ./candran/serpent.lua:35 +"math", -- ./candran/serpent.lua:35 +"string", -- ./candran/serpent.lua:35 +"table", -- ./candran/serpent.lua:35 +"os" -- ./candran/serpent.lua:35 +}) do -- ./candran/serpent.lua:35 +for k, v in pairs(type(G[g]) == "table" and G[g] or {}) do -- ./candran/serpent.lua:36 +globals[v] = g .. "." .. k -- ./candran/serpent.lua:36 +end -- ./candran/serpent.lua:36 +end -- ./candran/serpent.lua:36 +local function s(t, opts) -- ./candran/serpent.lua:38 +local name, indent, fatal, maxnum = opts["name"], opts["indent"], opts["fatal"], opts["maxnum"] -- ./candran/serpent.lua:39 +local sparse, custom, huge = opts["sparse"], opts["custom"], not opts["nohuge"] -- ./candran/serpent.lua:40 +local space, maxl = (opts["compact"] and "" or " "), (opts["maxlevel"] or math["huge"]) -- ./candran/serpent.lua:41 +local maxlen, metatostring = tonumber(opts["maxlength"]), opts["metatostring"] -- ./candran/serpent.lua:42 +local iname, comm = "_" .. (name or ""), opts["comment"] and (tonumber(opts["comment"]) or math["huge"]) -- ./candran/serpent.lua:43 +local numformat = opts["numformat"] or "%.17g" -- ./candran/serpent.lua:44 +local seen, sref, syms, symn = {}, { "local " .. iname .. "={}" }, {}, 0 -- ./candran/serpent.lua:45 +local function gensym(val) -- ./candran/serpent.lua:46 +return "_" .. (tostring(tostring(val)):gsub("[^%w]", ""):gsub("(%d%w+)", function(s) -- ./candran/serpent.lua:48 +if not syms[s] then -- ./candran/serpent.lua:48 +symn = symn + 1 -- ./candran/serpent.lua:48 +syms[s] = symn -- ./candran/serpent.lua:48 +end -- ./candran/serpent.lua:48 +return tostring(syms[s]) -- ./candran/serpent.lua:48 +end)) -- ./candran/serpent.lua:48 +end -- ./candran/serpent.lua:48 +local function safestr(s) -- ./candran/serpent.lua:49 +return type(s) == "number" and tostring(huge and snum[tostring(s)] or numformat:format(s)) or type(s) ~= "string" and tostring(s) or ("%q"):format(s):gsub("\ +", "n"):gsub("\26", "\\026") -- ./candran/serpent.lua:51 +end -- ./candran/serpent.lua:51 +local function comment(s, l) -- ./candran/serpent.lua:52 +return comm and (l or 0) < comm and " --[[" .. select(2, pcall(tostring, s)) .. "]]" or "" -- ./candran/serpent.lua:52 +end -- ./candran/serpent.lua:52 +local function globerr(s, l) -- ./candran/serpent.lua:53 +return globals[s] and globals[s] .. comment(s, l) or not fatal and safestr(select(2, pcall(tostring, s))) or error("Can't serialize " .. tostring(s)) -- ./candran/serpent.lua:54 +end -- ./candran/serpent.lua:54 +local function safename(path, name) -- ./candran/serpent.lua:55 +local n = name == nil and "" or name -- ./candran/serpent.lua:56 +local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] -- ./candran/serpent.lua:57 +local safe = plain and n or "[" .. safestr(n) .. "]" -- ./candran/serpent.lua:58 +return (path or "") .. (plain and path and "." or "") .. safe, safe -- ./candran/serpent.lua:59 +end -- ./candran/serpent.lua:59 +local alphanumsort = type(opts["sortkeys"]) == "function" and opts["sortkeys"] or function(k, o, n) -- ./candran/serpent.lua:60 +local maxn, to = tonumber(n) or 12, { -- ./candran/serpent.lua:61 +["number"] = "a", -- ./candran/serpent.lua:61 +["string"] = "b" -- ./candran/serpent.lua:61 +} -- ./candran/serpent.lua:61 +local function padnum(d) -- ./candran/serpent.lua:62 +return ("%0" .. tostring(maxn) .. "d"):format(tonumber(d)) -- ./candran/serpent.lua:62 +end -- ./candran/serpent.lua:62 +table["sort"](k, function(a, b) -- ./candran/serpent.lua:63 +return (k[a] ~= nil and 0 or to[type(a)] or "z") .. (tostring(a):gsub("%d+", padnum)) < (k[b] ~= nil and 0 or to[type(b)] or "z") .. (tostring(b):gsub("%d+", padnum)) -- ./candran/serpent.lua:66 +end) -- ./candran/serpent.lua:66 +end -- ./candran/serpent.lua:66 +local function val2str(t, name, indent, insref, path, plainindex, level) -- ./candran/serpent.lua:67 +local ttype, level, mt = type(t), (level or 0), getmetatable(t) -- ./candran/serpent.lua:68 +local spath, sname = safename(path, name) -- ./candran/serpent.lua:69 +local tag = plainindex and ((type(name) == "number") and "" or name .. space .. "=" .. space) or (name ~= nil and sname .. space .. "=" .. space or "") -- ./candran/serpent.lua:72 +if seen[t] then -- ./candran/serpent.lua:73 +sref[# sref + 1] = spath .. space .. "=" .. space .. seen[t] -- ./candran/serpent.lua:74 +return tag .. "nil" .. comment("ref", level) -- ./candran/serpent.lua:75 +end -- ./candran/serpent.lua:75 +if type(mt) == "table" and metatostring ~= false then -- ./candran/serpent.lua:77 +local to, tr = pcall(function() -- ./candran/serpent.lua:78 +return mt["__tostring"](t) -- ./candran/serpent.lua:78 +end) -- ./candran/serpent.lua:78 +local so, sr = pcall(function() -- ./candran/serpent.lua:79 +return mt["__serialize"](t) -- ./candran/serpent.lua:79 +end) -- ./candran/serpent.lua:79 +if (to or so) then -- ./candran/serpent.lua:80 +seen[t] = insref or spath -- ./candran/serpent.lua:81 +t = so and sr or tr -- ./candran/serpent.lua:82 +ttype = type(t) -- ./candran/serpent.lua:83 +end -- ./candran/serpent.lua:83 +end -- ./candran/serpent.lua:83 +if ttype == "table" then -- ./candran/serpent.lua:86 +if level >= maxl then -- ./candran/serpent.lua:87 +return tag .. "{}" .. comment("maxlvl", level) -- ./candran/serpent.lua:87 +end -- ./candran/serpent.lua:87 +seen[t] = insref or spath -- ./candran/serpent.lua:88 +if next(t) == nil then -- ./candran/serpent.lua:89 +return tag .. "{}" .. comment(t, level) -- ./candran/serpent.lua:89 +end -- ./candran/serpent.lua:89 +if maxlen and maxlen < 0 then -- ./candran/serpent.lua:90 +return tag .. "{}" .. comment("maxlen", level) -- ./candran/serpent.lua:90 +end -- ./candran/serpent.lua:90 +local maxn, o, out = math["min"](# t, maxnum or # t), {}, {} -- ./candran/serpent.lua:91 +for key = 1, maxn do -- ./candran/serpent.lua:92 +o[key] = key -- ./candran/serpent.lua:92 +end -- ./candran/serpent.lua:92 +if not maxnum or # o < maxnum then -- ./candran/serpent.lua:93 +local n = # o -- ./candran/serpent.lua:94 +for key in pairs(t) do -- ./candran/serpent.lua:95 +if o[key] ~= key then -- ./candran/serpent.lua:95 +n = n + 1 -- ./candran/serpent.lua:95 +o[n] = key -- ./candran/serpent.lua:95 +end -- ./candran/serpent.lua:95 +end -- ./candran/serpent.lua:95 +end -- ./candran/serpent.lua:95 +if maxnum and # o > maxnum then -- ./candran/serpent.lua:96 +o[maxnum + 1] = nil -- ./candran/serpent.lua:96 +end -- ./candran/serpent.lua:96 +if opts["sortkeys"] and # o > maxn then -- ./candran/serpent.lua:97 +alphanumsort(o, t, opts["sortkeys"]) -- ./candran/serpent.lua:97 +end -- ./candran/serpent.lua:97 +local sparse = sparse and # o > maxn -- ./candran/serpent.lua:98 +for n, key in ipairs(o) do -- ./candran/serpent.lua:99 +local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse -- ./candran/serpent.lua:100 +if opts["valignore"] and opts["valignore"][value] or opts["keyallow"] and not opts["keyallow"][key] or opts["keyignore"] and opts["keyignore"][key] or opts["valtypeignore"] and opts["valtypeignore"][type(value)] or sparse and value == nil then -- ./candran/serpent.lua:105 + -- ./candran/serpent.lua:106 +elseif ktype == "table" or ktype == "function" or badtype[ktype] then -- ./candran/serpent.lua:106 +if not seen[key] and not globals[key] then -- ./candran/serpent.lua:107 +sref[# sref + 1] = "placeholder" -- ./candran/serpent.lua:108 +local sname = safename(iname, gensym(key)) -- ./candran/serpent.lua:109 +sref[# sref] = val2str(key, sname, indent, sname, iname, true) -- ./candran/serpent.lua:110 +end -- ./candran/serpent.lua:110 +sref[# sref + 1] = "placeholder" -- ./candran/serpent.lua:111 +local path = seen[t] .. "[" .. tostring(seen[key] or globals[key] or gensym(key)) .. "]" -- ./candran/serpent.lua:112 +sref[# sref] = path .. space .. "=" .. space .. tostring(seen[value] or val2str(value, nil, indent, path)) -- ./candran/serpent.lua:113 +else -- ./candran/serpent.lua:113 +out[# out + 1] = val2str(value, key, indent, nil, seen[t], plainindex, level + 1) -- ./candran/serpent.lua:115 +if maxlen then -- ./candran/serpent.lua:116 +maxlen = maxlen - # out[# out] -- ./candran/serpent.lua:117 +if maxlen < 0 then -- ./candran/serpent.lua:118 +break -- ./candran/serpent.lua:118 +end -- ./candran/serpent.lua:118 +end -- ./candran/serpent.lua:118 +end -- ./candran/serpent.lua:118 +end -- ./candran/serpent.lua:118 +local prefix = string["rep"](indent or "", level) -- ./candran/serpent.lua:122 +local head = indent and "{\ +" .. prefix .. indent or "{" -- ./candran/serpent.lua:123 +local body = table["concat"](out, "," .. (indent and "\ +" .. prefix .. indent or space)) -- ./candran/serpent.lua:124 +local tail = indent and "\ +" .. prefix .. "}" or "}" -- ./candran/serpent.lua:125 +return (custom and custom(tag, head, body, tail, level) or tag .. head .. body .. tail) .. comment(t, level) -- ./candran/serpent.lua:126 +elseif badtype[ttype] then -- ./candran/serpent.lua:127 +seen[t] = insref or spath -- ./candran/serpent.lua:128 +return tag .. globerr(t, level) -- ./candran/serpent.lua:129 +elseif ttype == "function" then -- ./candran/serpent.lua:130 +seen[t] = insref or spath -- ./candran/serpent.lua:131 +if opts["nocode"] then -- ./candran/serpent.lua:132 +return tag .. "function() --[[..skipped..]] end" .. comment(t, level) -- ./candran/serpent.lua:132 +end -- ./candran/serpent.lua:132 +local ok, res = pcall(string["dump"], t) -- ./candran/serpent.lua:133 +local func = ok and "((loadstring or load)(" .. safestr(res) .. ",'@serialized'))" .. comment(t, level) -- ./candran/serpent.lua:134 +return tag .. (func or globerr(t, level)) -- ./candran/serpent.lua:135 +else -- ./candran/serpent.lua:135 +return tag .. safestr(t) -- ./candran/serpent.lua:136 +end -- ./candran/serpent.lua:136 +end -- ./candran/serpent.lua:136 +local sepr = indent and "\ +" or ";" .. space -- ./candran/serpent.lua:138 +local body = val2str(t, name, indent) -- ./candran/serpent.lua:139 +local tail = # sref > 1 and table["concat"](sref, sepr) .. sepr or "" -- ./candran/serpent.lua:140 +local warn = opts["comment"] and # sref > 1 and space .. "--[[incomplete output with shared/self-references skipped]]" or "" -- ./candran/serpent.lua:141 +return not name and body .. warn or "do local " .. body .. sepr .. tail .. "return " .. name .. sepr .. "end" -- ./candran/serpent.lua:142 +end -- ./candran/serpent.lua:142 +local function deserialize(data, opts) -- ./candran/serpent.lua:145 +local env = (opts and opts["safe"] == false) and G or setmetatable({}, { -- ./candran/serpent.lua:147 +["__index"] = function(t, k) -- ./candran/serpent.lua:148 +return t -- ./candran/serpent.lua:148 +end, -- ./candran/serpent.lua:148 +["__call"] = function(t, ...) -- ./candran/serpent.lua:149 +error("cannot call functions") -- ./candran/serpent.lua:149 +end -- ./candran/serpent.lua:149 +}) -- ./candran/serpent.lua:149 +local f, res = (loadstring or load)("return " .. data, nil, nil, env) -- ./candran/serpent.lua:151 +if not f then -- ./candran/serpent.lua:152 +f, res = (loadstring or load)(data, nil, nil, env) -- ./candran/serpent.lua:152 +end -- ./candran/serpent.lua:152 +if not f then -- ./candran/serpent.lua:153 +return f, res -- ./candran/serpent.lua:153 +end -- ./candran/serpent.lua:153 +if setfenv then -- ./candran/serpent.lua:154 +setfenv(f, env) -- ./candran/serpent.lua:154 +end -- ./candran/serpent.lua:154 +return pcall(f) -- ./candran/serpent.lua:155 +end -- ./candran/serpent.lua:155 +local function merge(a, b) -- ./candran/serpent.lua:158 +if b then -- ./candran/serpent.lua:158 +for k, v in pairs(b) do -- ./candran/serpent.lua:158 +a[k] = v -- ./candran/serpent.lua:158 +end -- ./candran/serpent.lua:158 +end -- ./candran/serpent.lua:158 +return a -- ./candran/serpent.lua:158 +end -- ./candran/serpent.lua:158 +return { -- ./candran/serpent.lua:159 +["_NAME"] = n, -- ./candran/serpent.lua:159 +["_COPYRIGHT"] = c, -- ./candran/serpent.lua:159 +["_DESCRIPTION"] = d, -- ./candran/serpent.lua:159 +["_VERSION"] = v, -- ./candran/serpent.lua:159 +["serialize"] = s, -- ./candran/serpent.lua:159 +["load"] = deserialize, -- ./candran/serpent.lua:160 +["dump"] = function(a, opts) -- ./candran/serpent.lua:161 +return s(a, merge({ -- ./candran/serpent.lua:161 +["name"] = "_", -- ./candran/serpent.lua:161 +["compact"] = true, -- ./candran/serpent.lua:161 +["sparse"] = true -- ./candran/serpent.lua:161 +}, opts)) -- ./candran/serpent.lua:161 +end, -- ./candran/serpent.lua:161 +["line"] = function(a, opts) -- ./candran/serpent.lua:162 +return s(a, merge({ -- ./candran/serpent.lua:162 +["sortkeys"] = true, -- ./candran/serpent.lua:162 +["comment"] = true -- ./candran/serpent.lua:162 +}, opts)) -- ./candran/serpent.lua:162 +end, -- ./candran/serpent.lua:162 +["block"] = function(a, opts) -- ./candran/serpent.lua:163 +return s(a, merge({ -- ./candran/serpent.lua:163 +["indent"] = " ", -- ./candran/serpent.lua:163 +["sortkeys"] = true, -- ./candran/serpent.lua:163 +["comment"] = true -- ./candran/serpent.lua:163 +}, opts)) -- ./candran/serpent.lua:163 +end -- ./candran/serpent.lua:163 +} -- ./candran/serpent.lua:163 +end -- ./candran/serpent.lua:163 +local serpent = _() or serpent -- ./candran/serpent.lua:167 +package["loaded"]["candran.serpent"] = serpent or true -- ./candran/serpent.lua:168 +local function _() -- ./candran/serpent.lua:172 local util = require("candran.util") -- ./compiler/lua54.can:1 local targetName = "Lua 5.4" -- ./compiler/lua54.can:3 local unpack = unpack or table["unpack"] -- ./compiler/lua54.can:5 @@ -6797,311 +7067,318 @@ return parser -- ./candran/can-parser/parser.lua:807 end -- ./candran/can-parser/parser.lua:807 local parser = _() or parser -- ./candran/can-parser/parser.lua:811 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:812 -local unpack = unpack or table["unpack"] -- candran.can:15 -local candran = { ["VERSION"] = "0.14.0" } -- candran.can:18 -package["loaded"]["candran"] = candran -- candran.can:20 -candran["default"] = { -- candran.can:23 -["target"] = "lua54", -- candran.can:24 -["indentation"] = "", -- candran.can:25 +local unpack = unpack or table["unpack"] -- candran.can:16 +local candran = { ["VERSION"] = "0.14.0" } -- candran.can:19 +package["loaded"]["candran"] = candran -- candran.can:21 +candran["default"] = { -- candran.can:24 +["target"] = "lua54", -- candran.can:25 +["indentation"] = "", -- candran.can:26 ["newline"] = "\ -", -- candran.can:26 -["variablePrefix"] = "__CAN_", -- candran.can:27 -["mapLines"] = true, -- candran.can:28 -["chunkname"] = "nil", -- candran.can:29 -["rewriteErrors"] = true -- candran.can:30 -} -- candran.can:30 -if _VERSION == "Lua 5.1" then -- candran.can:34 -if package["loaded"]["jit"] then -- candran.can:35 -candran["default"]["target"] = "luajit" -- candran.can:36 -else -- candran.can:36 -candran["default"]["target"] = "lua51" -- candran.can:38 -end -- candran.can:38 -elseif _VERSION == "Lua 5.2" then -- candran.can:40 -candran["default"]["target"] = "lua52" -- candran.can:41 -elseif _VERSION == "Lua 5.3" then -- candran.can:42 -candran["default"]["target"] = "lua53" -- candran.can:43 -end -- candran.can:43 -candran["preprocess"] = function(input, options) -- candran.can:53 -if options == nil then options = {} end -- candran.can:53 -options = util["merge"](candran["default"], options) -- candran.can:54 -local macros = { -- candran.can:55 -["functions"] = {}, -- candran.can:56 -["variables"] = {} -- candran.can:57 -} -- candran.can:57 -local preprocessor = "" -- candran.can:61 -local i = 0 -- candran.can:62 -local inLongString = false -- candran.can:63 -local inComment = false -- candran.can:64 +", -- candran.can:27 +["variablePrefix"] = "__CAN_", -- candran.can:28 +["mapLines"] = true, -- candran.can:29 +["chunkname"] = "nil", -- candran.can:30 +["rewriteErrors"] = true -- candran.can:31 +} -- candran.can:31 +if _VERSION == "Lua 5.1" then -- candran.can:35 +if package["loaded"]["jit"] then -- candran.can:36 +candran["default"]["target"] = "luajit" -- candran.can:37 +else -- candran.can:37 +candran["default"]["target"] = "lua51" -- candran.can:39 +end -- candran.can:39 +elseif _VERSION == "Lua 5.2" then -- candran.can:41 +candran["default"]["target"] = "lua52" -- candran.can:42 +elseif _VERSION == "Lua 5.3" then -- candran.can:43 +candran["default"]["target"] = "lua53" -- candran.can:44 +end -- candran.can:44 +candran["preprocess"] = function(input, options) -- candran.can:54 +if options == nil then options = {} end -- candran.can:54 +options = util["merge"](candran["default"], options) -- candran.can:55 +local macros = { -- candran.can:56 +["functions"] = {}, -- candran.can:57 +["variables"] = {} -- candran.can:58 +} -- candran.can:58 +local preprocessor = "" -- candran.can:62 +local i = 0 -- candran.can:63 +local inLongString = false -- candran.can:64 +local inComment = false -- candran.can:65 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:65 -i = i + (1) -- candran.can:66 -if inComment then -- candran.can:68 -inComment = not line:match("%]%]") -- candran.can:69 -elseif inLongString then -- candran.can:70 -inLongString = not line:match("%]%]") -- candran.can:71 -else -- candran.can:71 -if line:match("[^%-]%[%[") then -- candran.can:73 -inLongString = true -- candran.can:74 -elseif line:match("%-%-%[%[") then -- candran.can:75 -inComment = true -- candran.can:76 -end -- candran.can:76 -end -- candran.can:76 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:79 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:80 -else -- candran.can:80 -local l = line:sub(1, - 2) -- candran.can:82 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:83 +)") do -- candran.can:66 +i = i + (1) -- candran.can:67 +if inComment then -- candran.can:69 +inComment = not line:match("%]%]") -- candran.can:70 +elseif inLongString then -- candran.can:71 +inLongString = not line:match("%]%]") -- candran.can:72 +else -- candran.can:72 +if line:match("[^%-]%[%[") then -- candran.can:74 +inLongString = true -- candran.can:75 +elseif line:match("%-%-%[%[") then -- candran.can:76 +inComment = true -- candran.can:77 +end -- candran.can:77 +end -- candran.can:77 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:80 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:81 +else -- candran.can:81 +local l = line:sub(1, - 2) -- candran.can:83 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:84 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:84 -else -- candran.can:84 +") -- candran.can:85 +else -- candran.can:85 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:86 -end -- candran.can:86 -end -- candran.can:86 -end -- candran.can:86 -preprocessor = preprocessor .. ("return output") -- candran.can:90 -local env = util["merge"](_G, options) -- candran.can:93 -env["candran"] = candran -- candran.can:95 -env["output"] = "" -- candran.can:97 -env["import"] = function(modpath, margs) -- candran.can:104 -if margs == nil then margs = {} end -- candran.can:104 -local filepath = assert(util["search"](modpath, { -- candran.can:105 -"can", -- candran.can:105 -"lua" -- candran.can:105 -}), "No module named \"" .. modpath .. "\"") -- candran.can:105 -local f = io["open"](filepath) -- candran.can:108 -if not f then -- candran.can:109 -error("can't open the module file to import") -- candran.can:109 -end -- candran.can:109 -margs = util["merge"](options, { -- candran.can:111 -["chunkname"] = filepath, -- candran.can:111 -["loadLocal"] = true, -- candran.can:111 -["loadPackage"] = true -- candran.can:111 -}, margs) -- candran.can:111 -local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:112 -macros = util["recmerge"](macros, modmacros) -- candran.can:113 -f:close() -- candran.can:114 -local modname = modpath:match("[^%.]+$") -- candran.can:117 +") -- candran.can:87 +end -- candran.can:87 +end -- candran.can:87 +end -- candran.can:87 +preprocessor = preprocessor .. ("return output") -- candran.can:91 +local env = util["merge"](_G, options) -- candran.can:94 +env["candran"] = candran -- candran.can:96 +env["output"] = "" -- candran.can:98 +env["import"] = function(modpath, margs) -- candran.can:105 +if margs == nil then margs = {} end -- candran.can:105 +local filepath = assert(util["search"](modpath, { -- candran.can:106 +"can", -- candran.can:106 +"lua" -- candran.can:106 +}), "No module named \"" .. modpath .. "\"") -- candran.can:106 +local f = io["open"](filepath) -- candran.can:109 +if not f then -- candran.can:110 +error("can't open the module file to import") -- candran.can:110 +end -- candran.can:110 +margs = util["merge"](options, { -- candran.can:112 +["chunkname"] = filepath, -- candran.can:112 +["loadLocal"] = true, -- candran.can:112 +["loadPackage"] = true -- candran.can:112 +}, margs) -- candran.can:112 +local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:113 +macros = util["recmerge"](macros, modmacros) -- candran.can:114 +f:close() -- candran.can:115 +local modname = modpath:match("[^%.]+$") -- candran.can:118 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:126 -end -- candran.can:126 -env["include"] = function(file) -- candran.can:131 -local f = io["open"](file) -- candran.can:132 -if not f then -- candran.can:133 -error("can't open the file " .. file .. " to include") -- candran.can:133 -end -- candran.can:133 -env["write"](f:read("*a")) -- candran.can:134 -f:close() -- candran.can:135 -end -- candran.can:135 -env["write"] = function(...) -- candran.can:139 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:127 +end -- candran.can:127 +env["include"] = function(file) -- candran.can:132 +local f = io["open"](file) -- candran.can:133 +if not f then -- candran.can:134 +error("can't open the file " .. file .. " to include") -- candran.can:134 +end -- candran.can:134 +env["write"](f:read("*a")) -- candran.can:135 +f:close() -- candran.can:136 +end -- candran.can:136 +env["write"] = function(...) -- candran.can:140 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:140 -end -- candran.can:140 -env["placeholder"] = function(name) -- candran.can:144 -if env[name] then -- candran.can:145 -env["write"](env[name]) -- candran.can:146 -end -- candran.can:146 -end -- candran.can:146 -env["define"] = function(identifier, replacement) -- candran.can:149 -local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:151 -if not iast then -- candran.can:152 -return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:153 -end -- candran.can:153 -if type(replacement) == "string" then -- candran.can:156 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:157 -if not rast then -- candran.can:158 -return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:159 -end -- candran.can:159 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:162 -rast = rast[1][1] -- candran.can:163 -end -- candran.can:163 -replacement = rast -- candran.can:165 -elseif type(replacement) ~= "function" then -- candran.can:166 -error("bad argument #2 to 'define' (string or function expected)") -- candran.can:167 -end -- candran.can:167 -if iast["tag"] == "MacroFunction" then -- candran.can:170 -macros["functions"][iast[1][1]] = { -- candran.can:171 -["args"] = iast[2], -- candran.can:171 -["replacement"] = replacement -- candran.can:171 -} -- candran.can:171 -elseif iast["tag"] == "Id" then -- candran.can:172 -macros["variables"][iast[1]] = replacement -- candran.can:173 -else -- candran.can:173 -error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:175 -end -- candran.can:175 -end -- candran.can:175 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:180 -if not preprocess then -- candran.can:181 -return nil, "in preprocessor: " .. err -- candran.can:182 -end -- candran.can:182 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:185 -if not preprocess then -- candran.can:186 -return nil, "in preprocessor: " .. err -- candran.can:187 -end -- candran.can:187 -local success, output = pcall(preprocess) -- candran.can:191 -if not success then -- candran.can:192 -return nil, "in preprocessor: " .. output -- candran.can:193 -end -- candran.can:193 -return output, macros -- candran.can:196 +") -- candran.can:141 +end -- candran.can:141 +env["placeholder"] = function(name) -- candran.can:145 +if env[name] then -- candran.can:146 +env["write"](env[name]) -- candran.can:147 +end -- candran.can:147 +end -- candran.can:147 +env["define"] = function(identifier, replacement) -- candran.can:150 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:152 +if not iast then -- candran.can:153 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:154 +end -- candran.can:154 +if type(replacement) == "string" then -- candran.can:157 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:158 +if not rast then -- candran.can:159 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:160 +end -- candran.can:160 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:163 +rast = rast[1][1] -- candran.can:164 +end -- candran.can:164 +replacement = rast -- candran.can:166 +elseif type(replacement) ~= "function" then -- candran.can:167 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:168 +end -- candran.can:168 +if iast["tag"] == "MacroFunction" then -- candran.can:171 +macros["functions"][iast[1][1]] = { -- candran.can:172 +["args"] = iast[2], -- candran.can:172 +["replacement"] = replacement -- candran.can:172 +} -- candran.can:172 +elseif iast["tag"] == "Id" then -- candran.can:173 +macros["variables"][iast[1]] = replacement -- candran.can:174 +else -- candran.can:174 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:176 +end -- candran.can:176 +end -- candran.can:176 +env["define"]("__STR__(x)", function(x) -- candran.can:182 +return ("%q"):format(x) -- candran.can:182 +end) -- candran.can:182 +local s = require("candran.serpent") -- candran.can:183 +env["define"]("constexpr(expr)", function(expr) -- candran.can:184 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:185 +end) -- candran.can:185 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:189 +if not preprocess then -- candran.can:190 +return nil, "in preprocessor: " .. err -- candran.can:191 +end -- candran.can:191 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:194 +if not preprocess then -- candran.can:195 +return nil, "in preprocessor: " .. err -- candran.can:196 end -- candran.can:196 -candran["compile"] = function(input, options, macros) -- candran.can:206 -if options == nil then options = {} end -- candran.can:206 -options = util["merge"](candran["default"], options) -- candran.can:207 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:209 -if not ast then -- candran.can:211 -return nil, errmsg -- candran.can:212 -end -- candran.can:212 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:215 -end -- candran.can:215 -candran["make"] = function(code, options) -- candran.can:224 -local r, err = candran["preprocess"](code, options) -- candran.can:225 -if r then -- candran.can:226 -r, err = candran["compile"](r, options, err) -- candran.can:227 -if r then -- candran.can:228 -return r -- candran.can:229 -end -- candran.can:229 -end -- candran.can:229 -return r, err -- candran.can:232 -end -- candran.can:232 -local errorRewritingActive = false -- candran.can:235 -local codeCache = {} -- candran.can:236 -candran["loadfile"] = function(filepath, env, options) -- candran.can:239 -local f, err = io["open"](filepath) -- candran.can:240 -if not f then -- candran.can:241 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:242 -end -- candran.can:242 -local content = f:read("*a") -- candran.can:244 -f:close() -- candran.can:245 -return candran["load"](content, filepath, env, options) -- candran.can:247 -end -- candran.can:247 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:252 -if options == nil then options = {} end -- candran.can:252 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:253 -local code, err = candran["make"](chunk, options) -- candran.can:255 -if not code then -- candran.can:256 -return code, err -- candran.can:257 -end -- candran.can:257 -codeCache[options["chunkname"]] = code -- candran.can:260 -local f -- candran.can:261 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:262 -if f == nil then -- candran.can:267 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:268 -end -- candran.can:268 -if options["rewriteErrors"] == false then -- candran.can:271 -return f -- candran.can:272 -else -- candran.can:272 -return function(...) -- candran.can:274 -if not errorRewritingActive then -- candran.can:275 -errorRewritingActive = true -- candran.can:276 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:277 -errorRewritingActive = false -- candran.can:278 -if t[1] == false then -- candran.can:279 -error(t[2], 0) -- candran.can:280 -end -- candran.can:280 -return unpack(t, 2) -- candran.can:282 -else -- candran.can:282 -return f(...) -- candran.can:284 -end -- candran.can:284 -end -- candran.can:284 -end -- candran.can:284 -end -- candran.can:284 -candran["dofile"] = function(filename, options) -- candran.can:292 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:293 -if f == nil then -- candran.can:295 -error(err) -- candran.can:296 -else -- candran.can:296 -return f() -- candran.can:298 -end -- candran.can:298 -end -- candran.can:298 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:304 +local success, output = pcall(preprocess) -- candran.can:200 +if not success then -- candran.can:201 +return nil, "in preprocessor: " .. output -- candran.can:202 +end -- candran.can:202 +return output, macros -- candran.can:205 +end -- candran.can:205 +candran["compile"] = function(input, options, macros) -- candran.can:215 +if options == nil then options = {} end -- candran.can:215 +options = util["merge"](candran["default"], options) -- candran.can:216 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:218 +if not ast then -- candran.can:220 +return nil, errmsg -- candran.can:221 +end -- candran.can:221 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:224 +end -- candran.can:224 +candran["make"] = function(code, options) -- candran.can:233 +local r, err = candran["preprocess"](code, options) -- candran.can:234 +if r then -- candran.can:235 +r, err = candran["compile"](r, options, err) -- candran.can:236 +if r then -- candran.can:237 +return r -- candran.can:238 +end -- candran.can:238 +end -- candran.can:238 +return r, err -- candran.can:241 +end -- candran.can:241 +local errorRewritingActive = false -- candran.can:244 +local codeCache = {} -- candran.can:245 +candran["loadfile"] = function(filepath, env, options) -- candran.can:248 +local f, err = io["open"](filepath) -- candran.can:249 +if not f then -- candran.can:250 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:251 +end -- candran.can:251 +local content = f:read("*a") -- candran.can:253 +f:close() -- candran.can:254 +return candran["load"](content, filepath, env, options) -- candran.can:256 +end -- candran.can:256 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:261 +if options == nil then options = {} end -- candran.can:261 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:262 +local code, err = candran["make"](chunk, options) -- candran.can:264 +if not code then -- candran.can:265 +return code, err -- candran.can:266 +end -- candran.can:266 +codeCache[options["chunkname"]] = code -- candran.can:269 +local f -- candran.can:270 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:271 +if f == nil then -- candran.can:276 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:277 +end -- candran.can:277 +if options["rewriteErrors"] == false then -- candran.can:280 +return f -- candran.can:281 +else -- candran.can:281 +return function(...) -- candran.can:283 +if not errorRewritingActive then -- candran.can:284 +errorRewritingActive = true -- candran.can:285 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:286 +errorRewritingActive = false -- candran.can:287 +if t[1] == false then -- candran.can:288 +error(t[2], 0) -- candran.can:289 +end -- candran.can:289 +return unpack(t, 2) -- candran.can:291 +else -- candran.can:291 +return f(...) -- candran.can:293 +end -- candran.can:293 +end -- candran.can:293 +end -- candran.can:293 +end -- candran.can:293 +candran["dofile"] = function(filename, options) -- candran.can:301 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:302 +if f == nil then -- candran.can:304 +error(err) -- candran.can:305 +else -- candran.can:305 +return f() -- candran.can:307 +end -- candran.can:307 +end -- candran.can:307 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:313 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:305 -message = debug["traceback"](message, 2) -- candran.can:306 -end -- candran.can:306 +") then -- candran.can:314 +message = debug["traceback"](message, 2) -- candran.can:315 +end -- candran.can:315 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:308 -line = tonumber(line) -- candran.can:309 -local originalFile -- candran.can:311 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:312 -if strName then -- candran.can:313 -if codeCache[strName] then -- candran.can:314 -originalFile = codeCache[strName] -- candran.can:315 -source = strName -- candran.can:316 -end -- candran.can:316 -else -- candran.can:316 -do -- candran.can:319 -local fi -- candran.can:319 -fi = io["open"](source, "r") -- candran.can:319 -if fi then -- candran.can:319 -originalFile = fi:read("*a") -- candran.can:320 -fi:close() -- candran.can:321 -end -- candran.can:321 -end -- candran.can:321 -end -- candran.can:321 -if originalFile then -- candran.can:325 -local i = 0 -- candran.can:326 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:317 +line = tonumber(line) -- candran.can:318 +local originalFile -- candran.can:320 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:321 +if strName then -- candran.can:322 +if codeCache[strName] then -- candran.can:323 +originalFile = codeCache[strName] -- candran.can:324 +source = strName -- candran.can:325 +end -- candran.can:325 +else -- candran.can:325 +do -- candran.can:328 +local fi -- candran.can:328 +fi = io["open"](source, "r") -- candran.can:328 +if fi then -- candran.can:328 +originalFile = fi:read("*a") -- candran.can:329 +fi:close() -- candran.can:330 +end -- candran.can:330 +end -- candran.can:330 +end -- candran.can:330 +if originalFile then -- candran.can:334 +local i = 0 -- candran.can:335 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:327 -i = i + 1 -- candran.can:328 -if i == line then -- candran.can:329 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:330 -if lineMap then -- candran.can:331 -if extSource ~= source then -- candran.can:332 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:333 -else -- candran.can:333 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:335 -end -- candran.can:335 -end -- candran.can:335 -break -- candran.can:338 -end -- candran.can:338 -end -- candran.can:338 -end -- candran.can:338 -end) -- candran.can:338 -end -- candran.can:338 -candran["searcher"] = function(modpath) -- candran.can:346 -local filepath = util["search"](modpath, { "can" }) -- candran.can:347 -if not filepath then -- candran.can:348 -if _VERSION == "Lua 5.4" then -- candran.can:349 -return "no candran file in package.path" -- candran.can:350 -else -- candran.can:350 +") do -- candran.can:336 +i = i + 1 -- candran.can:337 +if i == line then -- candran.can:338 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:339 +if lineMap then -- candran.can:340 +if extSource ~= source then -- candran.can:341 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:342 +else -- candran.can:342 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:344 +end -- candran.can:344 +end -- candran.can:344 +break -- candran.can:347 +end -- candran.can:347 +end -- candran.can:347 +end -- candran.can:347 +end) -- candran.can:347 +end -- candran.can:347 +candran["searcher"] = function(modpath) -- candran.can:355 +local filepath = util["search"](modpath, { "can" }) -- candran.can:356 +if not filepath then -- candran.can:357 +if _VERSION == "Lua 5.4" then -- candran.can:358 +return "no candran file in package.path" -- candran.can:359 +else -- candran.can:359 return "\ -\9no candran file in package.path" -- candran.can:352 -end -- candran.can:352 -end -- candran.can:352 -return function(modpath) -- candran.can:355 -local r, s = candran["loadfile"](filepath) -- candran.can:356 -if r then -- candran.can:357 -return r(modpath, filepath) -- candran.can:358 -else -- candran.can:358 +\9no candran file in package.path" -- candran.can:361 +end -- candran.can:361 +end -- candran.can:361 +return function(modpath) -- candran.can:364 +local r, s = candran["loadfile"](filepath) -- candran.can:365 +if r then -- candran.can:366 +return r(modpath, filepath) -- candran.can:367 +else -- candran.can:367 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:360 -end -- candran.can:360 -end, filepath -- candran.can:362 -end -- candran.can:362 -candran["setup"] = function() -- candran.can:366 -local searchers = (function() -- candran.can:367 -if _VERSION == "Lua 5.1" then -- candran.can:367 -return package["loaders"] -- candran.can:368 -else -- candran.can:368 -return package["searchers"] -- candran.can:370 -end -- candran.can:370 -end)() -- candran.can:370 -for _, s in ipairs(searchers) do -- candran.can:373 -if s == candran["searcher"] then -- candran.can:374 -return candran -- candran.can:375 -end -- candran.can:375 -end -- candran.can:375 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:379 -return candran -- candran.can:380 -end -- candran.can:380 -return candran -- candran.can:383 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:369 +end -- candran.can:369 +end, filepath -- candran.can:371 +end -- candran.can:371 +candran["setup"] = function() -- candran.can:375 +local searchers = (function() -- candran.can:376 +if _VERSION == "Lua 5.1" then -- candran.can:376 +return package["loaders"] -- candran.can:377 +else -- candran.can:377 +return package["searchers"] -- candran.can:379 +end -- candran.can:379 +end)() -- candran.can:379 +for _, s in ipairs(searchers) do -- candran.can:382 +if s == candran["searcher"] then -- candran.can:383 +return candran -- candran.can:384 +end -- candran.can:384 +end -- candran.can:384 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:388 +return candran -- candran.can:389 +end -- candran.can:389 +return candran -- candran.can:392 diff --git a/candran/serpent.lua b/candran/serpent.lua new file mode 100644 index 0000000..067bb29 --- /dev/null +++ b/candran/serpent.lua @@ -0,0 +1,163 @@ +--[[ +Serpent source is released under the MIT License + +Copyright (c) 2012-2018 Paul Kulchenko (paul@kulchenko.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +]] +local n, v = "serpent", "0.302" -- (C) 2012-18 Paul Kulchenko; MIT License +local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" +local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'} +local badtype = {thread = true, userdata = true, cdata = true} +local getmetatable = debug and debug.getmetatable or getmetatable +local pairs = function(t) return next, t end -- avoid using __pairs in Lua 5.2+ +local keyword, globals, G = {}, {}, (_G or _ENV) +for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false', + 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end +for k,v in pairs(G) do globals[v] = k end -- build func to name mapping +for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do + for k,v in pairs(type(G[g]) == 'table' and G[g] or {}) do globals[v] = g..'.'..k end end + +local function s(t, opts) + local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum + local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge + local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge) + local maxlen, metatostring = tonumber(opts.maxlength), opts.metatostring + local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge) + local numformat = opts.numformat or "%.17g" + local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0 + local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)", + -- tostring(val) is needed because __tostring may return a non-string value + function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end + local function safestr(s) return type(s) == "number" and tostring(huge and snum[tostring(s)] or numformat:format(s)) + or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026 + or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end + local function comment(s,l) return comm and (l or 0) < comm and ' --[['..select(2, pcall(tostring, s))..']]' or '' end + local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal + and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end + local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r'] + local n = name == nil and '' or name + local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] + local safe = plain and n or '['..safestr(n)..']' + return (path or '')..(plain and path and '.' or '')..safe, safe end + local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding + local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'} + local function padnum(d) return ("%0"..tostring(maxn).."d"):format(tonumber(d)) end + table.sort(k, function(a,b) + -- sort numeric keys first: k[key] is not nil for numerical keys + return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum)) + < (k[b] ~= nil and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end + local function val2str(t, name, indent, insref, path, plainindex, level) + local ttype, level, mt = type(t), (level or 0), getmetatable(t) + local spath, sname = safename(path, name) + local tag = plainindex and + ((type(name) == "number") and '' or name..space..'='..space) or + (name ~= nil and sname..space..'='..space or '') + if seen[t] then -- already seen this element + sref[#sref+1] = spath..space..'='..space..seen[t] + return tag..'nil'..comment('ref', level) end + -- protect from those cases where __tostring may fail + if type(mt) == 'table' and metatostring ~= false then + local to, tr = pcall(function() return mt.__tostring(t) end) + local so, sr = pcall(function() return mt.__serialize(t) end) + if (to or so) then -- knows how to serialize itself + seen[t] = insref or spath + t = so and sr or tr + ttype = type(t) + end -- new value falls through to be serialized + end + if ttype == "table" then + if level >= maxl then return tag..'{}'..comment('maxlvl', level) end + seen[t] = insref or spath + if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty + if maxlen and maxlen < 0 then return tag..'{}'..comment('maxlen', level) end + local maxn, o, out = math.min(#t, maxnum or #t), {}, {} + for key = 1, maxn do o[key] = key end + if not maxnum or #o < maxnum then + local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables + for key in pairs(t) do if o[key] ~= key then n = n + 1; o[n] = key end end end + if maxnum and #o > maxnum then o[maxnum+1] = nil end + if opts.sortkeys and #o > maxn then alphanumsort(o, t, opts.sortkeys) end + local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output) + for n, key in ipairs(o) do + local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse + if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing + or opts.keyallow and not opts.keyallow[key] + or opts.keyignore and opts.keyignore[key] + or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types + or sparse and value == nil then -- skipping nils; do nothing + elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then + if not seen[key] and not globals[key] then + sref[#sref+1] = 'placeholder' + local sname = safename(iname, gensym(key)) -- iname is table for local variables + sref[#sref] = val2str(key,sname,indent,sname,iname,true) end + sref[#sref+1] = 'placeholder' + local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']' + sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path)) + else + out[#out+1] = val2str(value,key,indent,nil,seen[t],plainindex,level+1) + if maxlen then + maxlen = maxlen - #out[#out] + if maxlen < 0 then break end + end + end + end + local prefix = string.rep(indent or '', level) + local head = indent and '{\n'..prefix..indent or '{' + local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space)) + local tail = indent and "\n"..prefix..'}' or '}' + return (custom and custom(tag,head,body,tail,level) or tag..head..body..tail)..comment(t, level) + elseif badtype[ttype] then + seen[t] = insref or spath + return tag..globerr(t, level) + elseif ttype == 'function' then + seen[t] = insref or spath + if opts.nocode then return tag.."function() --[[..skipped..]] end"..comment(t, level) end + local ok, res = pcall(string.dump, t) + local func = ok and "((loadstring or load)("..safestr(res)..",'@serialized'))"..comment(t, level) + return tag..(func or globerr(t, level)) + else return tag..safestr(t) end -- handle all other types + end + local sepr = indent and "\n" or ";"..space + local body = val2str(t, name, indent) -- this call also populates sref + local tail = #sref>1 and table.concat(sref, sepr)..sepr or '' + local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or '' + return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end" +end + +local function deserialize(data, opts) + local env = (opts and opts.safe == false) and G + or setmetatable({}, { + __index = function(t,k) return t end, + __call = function(t,...) error("cannot call functions") end + }) + local f, res = (loadstring or load)('return '..data, nil, nil, env) + if not f then f, res = (loadstring or load)(data, nil, nil, env) end + if not f then return f, res end + if setfenv then setfenv(f, env) end + return pcall(f) +end + +local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end +return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s, + load = deserialize, + dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end, + line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end, + block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end } From b72aff807c9a0568a4f9e9d07e8842e1bc1823fd Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 11 Jun 2021 14:29:12 +0200 Subject: [PATCH 38/52] Update README --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 083e23a..6b502ac 100644 --- a/README.md +++ b/README.md @@ -461,11 +461,13 @@ The preprocessor has access to the following variables: #### Macros -Using `define(identifier, replacement)` in the preprocessor, you can define macros. Both identifier and replacement are expected to be string containing Candran/Lua code. +Using `define(identifier, replacement)` in the preprocessor, you can define macros. `identifier` is expected to be string containing Candran/Lua code (representing either a identifier or a function call), and `replacement` can be either a string containing Candran/Lua code or a function. -There are two types of macros: variables, which replace every instance of the given identifier with the replacement text; and functions, which will replace every call to this function with the replacement text, also replacing its arguments. The `...` will be replaced with every remaining argument. Macros can not be recursive. +There are two types of macros identifiers: variables, which replace every instance of the given identifier with the replacement; and functions, which will replace every call to this function with the replacement, also replacing its arguments. The `...` will be replaced with every remaining argument. Macros can not be recursive. -If the replacement text is empty, the macro will simply be removed from the compiled code. +If `replacement` is a string, the macro will be replaced with this string, replacing the macros arguments in the string. If `replacement` is a function, the function will be called every time the macro is encoutered, with the macro arguments passed as strings, and is expected to return a string that will be used as a replacement. + +If `replacement` is the empty empty, the macro will simply be removed from the compiled code. ```lua -- Variable macro @@ -481,8 +483,17 @@ log("network", "error") -- network: error #define("debug()", "") debug() -- not present in complied code + +#define("_assert(what, err)", function(what, err) +# return "if "..what.." then error("..err..") end" +#end) +_assert(5 = 2, "failed") -- replaced with if 5 = 2 then error("failed") end ``` +Candran provide some predefined macros by default: +* `__STR__(expr)`: returns a string litteral representing the expression (e.g., `__STR__(5 + 2)` expands to `"5 + 2"`) +* `constexpr(expr)`: calculate the result of the expression in the preprocessor, and returns a representation of the returned value, i.e. precalculate an expression at compile time + Compile targets --------------- Candran is based on the Lua 5.4 syntax, but can be compiled to Lua 5.4, Lua 5.3, Lua 5.2, LuaJIT, and Lua 5.1 compatible code. From dd22f2de3d782d7a2d7735b56a94819b46dd7a06 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 17 Jun 2021 18:03:34 +0200 Subject: [PATCH 39/52] Rename built-in macros to __*__, add flag to disable built-in macros --- README.md | 4 +- candran.can | 16 +- candran.lua | 567 ++++++++++++++++++++++++++-------------------------- 3 files changed, 297 insertions(+), 290 deletions(-) diff --git a/README.md b/README.md index 6b502ac..8132861 100644 --- a/README.md +++ b/README.md @@ -492,7 +492,8 @@ _assert(5 = 2, "failed") -- replaced with if 5 = 2 then error("failed") end Candran provide some predefined macros by default: * `__STR__(expr)`: returns a string litteral representing the expression (e.g., `__STR__(5 + 2)` expands to `"5 + 2"`) -* `constexpr(expr)`: calculate the result of the expression in the preprocessor, and returns a representation of the returned value, i.e. precalculate an expression at compile time +* `__CONSTEXPR__(expr)`: calculate the result of the expression in the preprocessor, and returns a representation of the returned value, i.e. precalculate an expression at compile time +You can disable these built-in macros using the `noBuiltInMacros` compiler option. Compile targets --------------- @@ -669,6 +670,7 @@ variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local varia mapLines = true -- if true, compiled files will contain comments at the end of each line indicating the associated line and source file. Needed for error rewriting. chunkname = "nil" -- the chunkname used when running code using the helper functions and writing the line origin comments. Candran will try to set it to the original filename if it knows it. rewriteErrors = true -- true to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall(). +noBuiltInMacros = false -- true to disable built-in macros __*__ ``` You can change the defaults used for these variables in the table `candran.default`. diff --git a/candran.can b/candran.can index cf1a7ce..159ac33 100644 --- a/candran.can +++ b/candran.can @@ -28,7 +28,8 @@ candran.default = { variablePrefix = "__CAN_", mapLines = true, chunkname = "nil", - rewriteErrors = true + rewriteErrors = true, + noBuiltInMacros = false } -- Autodetect version @@ -178,12 +179,13 @@ function candran.preprocess(input, options={}) end -- default macros - -- TODO make it optional - env.define("__STR__(x)", function(x) return ("%q"):format(x) end) - local s = require("candran.serpent") - env.define("constexpr(expr)", function(expr) - return s.block(assert(candran.load(expr))(), {fatal = true}) - end) + if not options.noBuiltInMacros then + env.define("__STR__(x)", function(x) return ("%q"):format(x) end) + local s = require("candran.serpent") + env.define("__CONSTEXPR__(expr)", function(expr) + return s.block(assert(candran.load(expr))(), {fatal = true}) + end) + end -- compile & load preprocessor local preprocess, err = candran.compile(preprocessor, options) diff --git a/candran.lua b/candran.lua index eb17932..82260c7 100644 --- a/candran.lua +++ b/candran.lua @@ -7078,307 +7078,310 @@ candran["default"] = { -- candran.can:24 ["variablePrefix"] = "__CAN_", -- candran.can:28 ["mapLines"] = true, -- candran.can:29 ["chunkname"] = "nil", -- candran.can:30 -["rewriteErrors"] = true -- candran.can:31 -} -- candran.can:31 -if _VERSION == "Lua 5.1" then -- candran.can:35 -if package["loaded"]["jit"] then -- candran.can:36 -candran["default"]["target"] = "luajit" -- candran.can:37 -else -- candran.can:37 -candran["default"]["target"] = "lua51" -- candran.can:39 -end -- candran.can:39 -elseif _VERSION == "Lua 5.2" then -- candran.can:41 -candran["default"]["target"] = "lua52" -- candran.can:42 -elseif _VERSION == "Lua 5.3" then -- candran.can:43 -candran["default"]["target"] = "lua53" -- candran.can:44 -end -- candran.can:44 -candran["preprocess"] = function(input, options) -- candran.can:54 -if options == nil then options = {} end -- candran.can:54 -options = util["merge"](candran["default"], options) -- candran.can:55 -local macros = { -- candran.can:56 -["functions"] = {}, -- candran.can:57 -["variables"] = {} -- candran.can:58 -} -- candran.can:58 -local preprocessor = "" -- candran.can:62 -local i = 0 -- candran.can:63 -local inLongString = false -- candran.can:64 -local inComment = false -- candran.can:65 +["rewriteErrors"] = true, -- candran.can:31 +["noBuiltInMacros"] = false -- candran.can:32 +} -- candran.can:32 +if _VERSION == "Lua 5.1" then -- candran.can:36 +if package["loaded"]["jit"] then -- candran.can:37 +candran["default"]["target"] = "luajit" -- candran.can:38 +else -- candran.can:38 +candran["default"]["target"] = "lua51" -- candran.can:40 +end -- candran.can:40 +elseif _VERSION == "Lua 5.2" then -- candran.can:42 +candran["default"]["target"] = "lua52" -- candran.can:43 +elseif _VERSION == "Lua 5.3" then -- candran.can:44 +candran["default"]["target"] = "lua53" -- candran.can:45 +end -- candran.can:45 +candran["preprocess"] = function(input, options) -- candran.can:55 +if options == nil then options = {} end -- candran.can:55 +options = util["merge"](candran["default"], options) -- candran.can:56 +local macros = { -- candran.can:57 +["functions"] = {}, -- candran.can:58 +["variables"] = {} -- candran.can:59 +} -- candran.can:59 +local preprocessor = "" -- candran.can:63 +local i = 0 -- candran.can:64 +local inLongString = false -- candran.can:65 +local inComment = false -- candran.can:66 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:66 -i = i + (1) -- candran.can:67 -if inComment then -- candran.can:69 -inComment = not line:match("%]%]") -- candran.can:70 -elseif inLongString then -- candran.can:71 -inLongString = not line:match("%]%]") -- candran.can:72 -else -- candran.can:72 -if line:match("[^%-]%[%[") then -- candran.can:74 -inLongString = true -- candran.can:75 -elseif line:match("%-%-%[%[") then -- candran.can:76 -inComment = true -- candran.can:77 -end -- candran.can:77 -end -- candran.can:77 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:80 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:81 -else -- candran.can:81 -local l = line:sub(1, - 2) -- candran.can:83 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:84 +)") do -- candran.can:67 +i = i + (1) -- candran.can:68 +if inComment then -- candran.can:70 +inComment = not line:match("%]%]") -- candran.can:71 +elseif inLongString then -- candran.can:72 +inLongString = not line:match("%]%]") -- candran.can:73 +else -- candran.can:73 +if line:match("[^%-]%[%[") then -- candran.can:75 +inLongString = true -- candran.can:76 +elseif line:match("%-%-%[%[") then -- candran.can:77 +inComment = true -- candran.can:78 +end -- candran.can:78 +end -- candran.can:78 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:81 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:82 +else -- candran.can:82 +local l = line:sub(1, - 2) -- candran.can:84 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:85 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:85 -else -- candran.can:85 +") -- candran.can:86 +else -- candran.can:86 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:87 -end -- candran.can:87 -end -- candran.can:87 -end -- candran.can:87 -preprocessor = preprocessor .. ("return output") -- candran.can:91 -local env = util["merge"](_G, options) -- candran.can:94 -env["candran"] = candran -- candran.can:96 -env["output"] = "" -- candran.can:98 -env["import"] = function(modpath, margs) -- candran.can:105 -if margs == nil then margs = {} end -- candran.can:105 -local filepath = assert(util["search"](modpath, { -- candran.can:106 -"can", -- candran.can:106 -"lua" -- candran.can:106 -}), "No module named \"" .. modpath .. "\"") -- candran.can:106 -local f = io["open"](filepath) -- candran.can:109 -if not f then -- candran.can:110 -error("can't open the module file to import") -- candran.can:110 -end -- candran.can:110 -margs = util["merge"](options, { -- candran.can:112 -["chunkname"] = filepath, -- candran.can:112 -["loadLocal"] = true, -- candran.can:112 -["loadPackage"] = true -- candran.can:112 -}, margs) -- candran.can:112 -local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:113 -macros = util["recmerge"](macros, modmacros) -- candran.can:114 -f:close() -- candran.can:115 -local modname = modpath:match("[^%.]+$") -- candran.can:118 +") -- candran.can:88 +end -- candran.can:88 +end -- candran.can:88 +end -- candran.can:88 +preprocessor = preprocessor .. ("return output") -- candran.can:92 +local env = util["merge"](_G, options) -- candran.can:95 +env["candran"] = candran -- candran.can:97 +env["output"] = "" -- candran.can:99 +env["import"] = function(modpath, margs) -- candran.can:106 +if margs == nil then margs = {} end -- candran.can:106 +local filepath = assert(util["search"](modpath, { -- candran.can:107 +"can", -- candran.can:107 +"lua" -- candran.can:107 +}), "No module named \"" .. modpath .. "\"") -- candran.can:107 +local f = io["open"](filepath) -- candran.can:110 +if not f then -- candran.can:111 +error("can't open the module file to import") -- candran.can:111 +end -- candran.can:111 +margs = util["merge"](options, { -- candran.can:113 +["chunkname"] = filepath, -- candran.can:113 +["loadLocal"] = true, -- candran.can:113 +["loadPackage"] = true -- candran.can:113 +}, margs) -- candran.can:113 +local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:114 +macros = util["recmerge"](macros, modmacros) -- candran.can:115 +f:close() -- candran.can:116 +local modname = modpath:match("[^%.]+$") -- candran.can:119 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:127 -end -- candran.can:127 -env["include"] = function(file) -- candran.can:132 -local f = io["open"](file) -- candran.can:133 -if not f then -- candran.can:134 -error("can't open the file " .. file .. " to include") -- candran.can:134 -end -- candran.can:134 -env["write"](f:read("*a")) -- candran.can:135 -f:close() -- candran.can:136 -end -- candran.can:136 -env["write"] = function(...) -- candran.can:140 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:128 +end -- candran.can:128 +env["include"] = function(file) -- candran.can:133 +local f = io["open"](file) -- candran.can:134 +if not f then -- candran.can:135 +error("can't open the file " .. file .. " to include") -- candran.can:135 +end -- candran.can:135 +env["write"](f:read("*a")) -- candran.can:136 +f:close() -- candran.can:137 +end -- candran.can:137 +env["write"] = function(...) -- candran.can:141 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:141 -end -- candran.can:141 -env["placeholder"] = function(name) -- candran.can:145 -if env[name] then -- candran.can:146 -env["write"](env[name]) -- candran.can:147 -end -- candran.can:147 -end -- candran.can:147 -env["define"] = function(identifier, replacement) -- candran.can:150 -local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:152 -if not iast then -- candran.can:153 -return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:154 -end -- candran.can:154 -if type(replacement) == "string" then -- candran.can:157 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:158 -if not rast then -- candran.can:159 -return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:160 -end -- candran.can:160 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:163 -rast = rast[1][1] -- candran.can:164 -end -- candran.can:164 -replacement = rast -- candran.can:166 -elseif type(replacement) ~= "function" then -- candran.can:167 -error("bad argument #2 to 'define' (string or function expected)") -- candran.can:168 -end -- candran.can:168 -if iast["tag"] == "MacroFunction" then -- candran.can:171 -macros["functions"][iast[1][1]] = { -- candran.can:172 -["args"] = iast[2], -- candran.can:172 -["replacement"] = replacement -- candran.can:172 -} -- candran.can:172 -elseif iast["tag"] == "Id" then -- candran.can:173 -macros["variables"][iast[1]] = replacement -- candran.can:174 -else -- candran.can:174 -error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:176 -end -- candran.can:176 -end -- candran.can:176 -env["define"]("__STR__(x)", function(x) -- candran.can:182 -return ("%q"):format(x) -- candran.can:182 -end) -- candran.can:182 -local s = require("candran.serpent") -- candran.can:183 -env["define"]("constexpr(expr)", function(expr) -- candran.can:184 -return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:185 -end) -- candran.can:185 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:189 -if not preprocess then -- candran.can:190 -return nil, "in preprocessor: " .. err -- candran.can:191 -end -- candran.can:191 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:194 -if not preprocess then -- candran.can:195 -return nil, "in preprocessor: " .. err -- candran.can:196 -end -- candran.can:196 -local success, output = pcall(preprocess) -- candran.can:200 -if not success then -- candran.can:201 -return nil, "in preprocessor: " .. output -- candran.can:202 -end -- candran.can:202 -return output, macros -- candran.can:205 -end -- candran.can:205 -candran["compile"] = function(input, options, macros) -- candran.can:215 -if options == nil then options = {} end -- candran.can:215 -options = util["merge"](candran["default"], options) -- candran.can:216 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:218 -if not ast then -- candran.can:220 -return nil, errmsg -- candran.can:221 -end -- candran.can:221 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:224 -end -- candran.can:224 -candran["make"] = function(code, options) -- candran.can:233 -local r, err = candran["preprocess"](code, options) -- candran.can:234 -if r then -- candran.can:235 -r, err = candran["compile"](r, options, err) -- candran.can:236 +") -- candran.can:142 +end -- candran.can:142 +env["placeholder"] = function(name) -- candran.can:146 +if env[name] then -- candran.can:147 +env["write"](env[name]) -- candran.can:148 +end -- candran.can:148 +end -- candran.can:148 +env["define"] = function(identifier, replacement) -- candran.can:151 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:153 +if not iast then -- candran.can:154 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:155 +end -- candran.can:155 +if type(replacement) == "string" then -- candran.can:158 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:159 +if not rast then -- candran.can:160 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:161 +end -- candran.can:161 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:164 +rast = rast[1][1] -- candran.can:165 +end -- candran.can:165 +replacement = rast -- candran.can:167 +elseif type(replacement) ~= "function" then -- candran.can:168 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:169 +end -- candran.can:169 +if iast["tag"] == "MacroFunction" then -- candran.can:172 +macros["functions"][iast[1][1]] = { -- candran.can:173 +["args"] = iast[2], -- candran.can:173 +["replacement"] = replacement -- candran.can:173 +} -- candran.can:173 +elseif iast["tag"] == "Id" then -- candran.can:174 +macros["variables"][iast[1]] = replacement -- candran.can:175 +else -- candran.can:175 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:177 +end -- candran.can:177 +end -- candran.can:177 +if not options["noBuiltInMacros"] then -- candran.can:182 +env["define"]("__STR__(x)", function(x) -- candran.can:183 +return ("%q"):format(x) -- candran.can:183 +end) -- candran.can:183 +local s = require("candran.serpent") -- candran.can:184 +env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:185 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:186 +end) -- candran.can:186 +end -- candran.can:186 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:191 +if not preprocess then -- candran.can:192 +return nil, "in preprocessor: " .. err -- candran.can:193 +end -- candran.can:193 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:196 +if not preprocess then -- candran.can:197 +return nil, "in preprocessor: " .. err -- candran.can:198 +end -- candran.can:198 +local success, output = pcall(preprocess) -- candran.can:202 +if not success then -- candran.can:203 +return nil, "in preprocessor: " .. output -- candran.can:204 +end -- candran.can:204 +return output, macros -- candran.can:207 +end -- candran.can:207 +candran["compile"] = function(input, options, macros) -- candran.can:217 +if options == nil then options = {} end -- candran.can:217 +options = util["merge"](candran["default"], options) -- candran.can:218 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:220 +if not ast then -- candran.can:222 +return nil, errmsg -- candran.can:223 +end -- candran.can:223 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:226 +end -- candran.can:226 +candran["make"] = function(code, options) -- candran.can:235 +local r, err = candran["preprocess"](code, options) -- candran.can:236 if r then -- candran.can:237 -return r -- candran.can:238 -end -- candran.can:238 -end -- candran.can:238 -return r, err -- candran.can:241 -end -- candran.can:241 -local errorRewritingActive = false -- candran.can:244 -local codeCache = {} -- candran.can:245 -candran["loadfile"] = function(filepath, env, options) -- candran.can:248 -local f, err = io["open"](filepath) -- candran.can:249 -if not f then -- candran.can:250 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:251 -end -- candran.can:251 -local content = f:read("*a") -- candran.can:253 -f:close() -- candran.can:254 -return candran["load"](content, filepath, env, options) -- candran.can:256 -end -- candran.can:256 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:261 -if options == nil then options = {} end -- candran.can:261 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:262 -local code, err = candran["make"](chunk, options) -- candran.can:264 -if not code then -- candran.can:265 -return code, err -- candran.can:266 -end -- candran.can:266 -codeCache[options["chunkname"]] = code -- candran.can:269 -local f -- candran.can:270 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:271 -if f == nil then -- candran.can:276 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:277 -end -- candran.can:277 -if options["rewriteErrors"] == false then -- candran.can:280 -return f -- candran.can:281 -else -- candran.can:281 -return function(...) -- candran.can:283 -if not errorRewritingActive then -- candran.can:284 -errorRewritingActive = true -- candran.can:285 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:286 -errorRewritingActive = false -- candran.can:287 -if t[1] == false then -- candran.can:288 -error(t[2], 0) -- candran.can:289 -end -- candran.can:289 -return unpack(t, 2) -- candran.can:291 -else -- candran.can:291 -return f(...) -- candran.can:293 -end -- candran.can:293 -end -- candran.can:293 -end -- candran.can:293 -end -- candran.can:293 -candran["dofile"] = function(filename, options) -- candran.can:301 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:302 -if f == nil then -- candran.can:304 -error(err) -- candran.can:305 -else -- candran.can:305 -return f() -- candran.can:307 -end -- candran.can:307 -end -- candran.can:307 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:313 +r, err = candran["compile"](r, options, err) -- candran.can:238 +if r then -- candran.can:239 +return r -- candran.can:240 +end -- candran.can:240 +end -- candran.can:240 +return r, err -- candran.can:243 +end -- candran.can:243 +local errorRewritingActive = false -- candran.can:246 +local codeCache = {} -- candran.can:247 +candran["loadfile"] = function(filepath, env, options) -- candran.can:250 +local f, err = io["open"](filepath) -- candran.can:251 +if not f then -- candran.can:252 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:253 +end -- candran.can:253 +local content = f:read("*a") -- candran.can:255 +f:close() -- candran.can:256 +return candran["load"](content, filepath, env, options) -- candran.can:258 +end -- candran.can:258 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:263 +if options == nil then options = {} end -- candran.can:263 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:264 +local code, err = candran["make"](chunk, options) -- candran.can:266 +if not code then -- candran.can:267 +return code, err -- candran.can:268 +end -- candran.can:268 +codeCache[options["chunkname"]] = code -- candran.can:271 +local f -- candran.can:272 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:273 +if f == nil then -- candran.can:278 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:279 +end -- candran.can:279 +if options["rewriteErrors"] == false then -- candran.can:282 +return f -- candran.can:283 +else -- candran.can:283 +return function(...) -- candran.can:285 +if not errorRewritingActive then -- candran.can:286 +errorRewritingActive = true -- candran.can:287 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:288 +errorRewritingActive = false -- candran.can:289 +if t[1] == false then -- candran.can:290 +error(t[2], 0) -- candran.can:291 +end -- candran.can:291 +return unpack(t, 2) -- candran.can:293 +else -- candran.can:293 +return f(...) -- candran.can:295 +end -- candran.can:295 +end -- candran.can:295 +end -- candran.can:295 +end -- candran.can:295 +candran["dofile"] = function(filename, options) -- candran.can:303 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:304 +if f == nil then -- candran.can:306 +error(err) -- candran.can:307 +else -- candran.can:307 +return f() -- candran.can:309 +end -- candran.can:309 +end -- candran.can:309 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:315 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:314 -message = debug["traceback"](message, 2) -- candran.can:315 -end -- candran.can:315 +") then -- candran.can:316 +message = debug["traceback"](message, 2) -- candran.can:317 +end -- candran.can:317 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:317 -line = tonumber(line) -- candran.can:318 -local originalFile -- candran.can:320 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:321 -if strName then -- candran.can:322 -if codeCache[strName] then -- candran.can:323 -originalFile = codeCache[strName] -- candran.can:324 -source = strName -- candran.can:325 -end -- candran.can:325 -else -- candran.can:325 -do -- candran.can:328 -local fi -- candran.can:328 -fi = io["open"](source, "r") -- candran.can:328 -if fi then -- candran.can:328 -originalFile = fi:read("*a") -- candran.can:329 -fi:close() -- candran.can:330 -end -- candran.can:330 -end -- candran.can:330 -end -- candran.can:330 -if originalFile then -- candran.can:334 -local i = 0 -- candran.can:335 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:319 +line = tonumber(line) -- candran.can:320 +local originalFile -- candran.can:322 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:323 +if strName then -- candran.can:324 +if codeCache[strName] then -- candran.can:325 +originalFile = codeCache[strName] -- candran.can:326 +source = strName -- candran.can:327 +end -- candran.can:327 +else -- candran.can:327 +do -- candran.can:330 +local fi -- candran.can:330 +fi = io["open"](source, "r") -- candran.can:330 +if fi then -- candran.can:330 +originalFile = fi:read("*a") -- candran.can:331 +fi:close() -- candran.can:332 +end -- candran.can:332 +end -- candran.can:332 +end -- candran.can:332 +if originalFile then -- candran.can:336 +local i = 0 -- candran.can:337 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:336 -i = i + 1 -- candran.can:337 -if i == line then -- candran.can:338 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:339 -if lineMap then -- candran.can:340 -if extSource ~= source then -- candran.can:341 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:342 -else -- candran.can:342 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:344 -end -- candran.can:344 -end -- candran.can:344 -break -- candran.can:347 -end -- candran.can:347 -end -- candran.can:347 -end -- candran.can:347 -end) -- candran.can:347 -end -- candran.can:347 -candran["searcher"] = function(modpath) -- candran.can:355 -local filepath = util["search"](modpath, { "can" }) -- candran.can:356 -if not filepath then -- candran.can:357 -if _VERSION == "Lua 5.4" then -- candran.can:358 -return "no candran file in package.path" -- candran.can:359 -else -- candran.can:359 +") do -- candran.can:338 +i = i + 1 -- candran.can:339 +if i == line then -- candran.can:340 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:341 +if lineMap then -- candran.can:342 +if extSource ~= source then -- candran.can:343 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:344 +else -- candran.can:344 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:346 +end -- candran.can:346 +end -- candran.can:346 +break -- candran.can:349 +end -- candran.can:349 +end -- candran.can:349 +end -- candran.can:349 +end) -- candran.can:349 +end -- candran.can:349 +candran["searcher"] = function(modpath) -- candran.can:357 +local filepath = util["search"](modpath, { "can" }) -- candran.can:358 +if not filepath then -- candran.can:359 +if _VERSION == "Lua 5.4" then -- candran.can:360 +return "no candran file in package.path" -- candran.can:361 +else -- candran.can:361 return "\ -\9no candran file in package.path" -- candran.can:361 -end -- candran.can:361 -end -- candran.can:361 -return function(modpath) -- candran.can:364 -local r, s = candran["loadfile"](filepath) -- candran.can:365 -if r then -- candran.can:366 -return r(modpath, filepath) -- candran.can:367 -else -- candran.can:367 +\9no candran file in package.path" -- candran.can:363 +end -- candran.can:363 +end -- candran.can:363 +return function(modpath) -- candran.can:366 +local r, s = candran["loadfile"](filepath) -- candran.can:367 +if r then -- candran.can:368 +return r(modpath, filepath) -- candran.can:369 +else -- candran.can:369 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:369 -end -- candran.can:369 -end, filepath -- candran.can:371 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:371 end -- candran.can:371 -candran["setup"] = function() -- candran.can:375 -local searchers = (function() -- candran.can:376 -if _VERSION == "Lua 5.1" then -- candran.can:376 -return package["loaders"] -- candran.can:377 -else -- candran.can:377 -return package["searchers"] -- candran.can:379 -end -- candran.can:379 -end)() -- candran.can:379 -for _, s in ipairs(searchers) do -- candran.can:382 -if s == candran["searcher"] then -- candran.can:383 -return candran -- candran.can:384 -end -- candran.can:384 -end -- candran.can:384 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:388 -return candran -- candran.can:389 -end -- candran.can:389 -return candran -- candran.can:392 +end, filepath -- candran.can:373 +end -- candran.can:373 +candran["setup"] = function() -- candran.can:377 +local searchers = (function() -- candran.can:378 +if _VERSION == "Lua 5.1" then -- candran.can:378 +return package["loaders"] -- candran.can:379 +else -- candran.can:379 +return package["searchers"] -- candran.can:381 +end -- candran.can:381 +end)() -- candran.can:381 +for _, s in ipairs(searchers) do -- candran.can:384 +if s == candran["searcher"] then -- candran.can:385 +return candran -- candran.can:386 +end -- candran.can:386 +end -- candran.can:386 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:390 +return candran -- candran.can:391 +end -- candran.can:391 +return candran -- candran.can:394 From e9ae8e21a3b8dfcb456fedb1394abc6749955268 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 17 Jun 2021 19:45:53 +0200 Subject: [PATCH 40/52] Use argparse to parse CLI args, separate preprocessor constants from options --- README.md | 7 +- bin/can | 44 +++--- bin/canc | 85 ++++++----- candran.can | 8 +- candran.lua | 258 +++++++++++++------------------- candran/cmdline.lua | 126 ---------------- candran/util.can | 65 ++++++++ rockspec/candran-scm-1.rockspec | 6 +- 8 files changed, 253 insertions(+), 346 deletions(-) delete mode 100644 candran/cmdline.lua diff --git a/README.md b/README.md index 8132861..66992aa 100644 --- a/README.md +++ b/README.md @@ -493,7 +493,7 @@ _assert(5 = 2, "failed") -- replaced with if 5 = 2 then error("failed") end Candran provide some predefined macros by default: * `__STR__(expr)`: returns a string litteral representing the expression (e.g., `__STR__(5 + 2)` expands to `"5 + 2"`) * `__CONSTEXPR__(expr)`: calculate the result of the expression in the preprocessor, and returns a representation of the returned value, i.e. precalculate an expression at compile time -You can disable these built-in macros using the `noBuiltInMacros` compiler option. +You can disable these built-in macros using the `builtInMacros` compiler option. Compile targets --------------- @@ -663,14 +663,15 @@ at the top of your main Lua file. If a Candran file is found when you call ```re You can give arbitrary options to the compiler and preprocessor, but Candran already provide and uses these with their associated default values: ```lua -target = "lua53" -- compiler target. "lua53", "lua52", "luajit" or "lua51" (default is automatically selected based on the Lua version used). +target = "lua53" -- compiler target. "lua54", "lua53", "lua52", "luajit" or "lua51" (default is automatically selected based on the Lua version used). indentation = "" -- character(s) used for indentation in the compiled file. newline = "\n" -- character(s) used for newlines in the compiled file. variablePrefix = "__CAN_" -- Prefix used when Candran needs to set a local variable to provide some functionality (example: to load LuaJIT's bit lib when using bitwise operators). mapLines = true -- if true, compiled files will contain comments at the end of each line indicating the associated line and source file. Needed for error rewriting. chunkname = "nil" -- the chunkname used when running code using the helper functions and writing the line origin comments. Candran will try to set it to the original filename if it knows it. rewriteErrors = true -- true to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall(). -noBuiltInMacros = false -- true to disable built-in macros __*__ +builtInMacros = true -- false to disable built-in macros __*__ +preprocessorEnv = {} -- environment to merge with the preprocessor environement ``` You can change the defaults used for these variables in the table `candran.default`. diff --git a/bin/can b/bin/can index 8c4cdc7..3ab0f36 100644 --- a/bin/can +++ b/bin/can @@ -1,28 +1,30 @@ #!/usr/bin/env lua local candran = require("candran").setup() -local cmdline = require("candran.cmdline") +local util = require("candran.util") +local argparse = require("argparse") -local args = cmdline(arg) +-- Parse args -- -if args.help or args.h then - print("Candran "..candran.VERSION.." interpreter by Reuh") - print("Usage: "..arg[0].." [options] filename") - print("Specify no options to start the REPL.") - print("Use - instead of a filename to read from the standard input.") - print("Interpreter options:") - print(" -help or -h print this text") - print("Default options:") - for opt, val in pairs(candran.default) do - if type(val) == "string" then val = val:gsub("\n", "\\n") end - print((" %s=%q"):format(opt, tostring(val))) - end - return -end +local parser = argparse() + :name "can" + :description("Candran "..candran.VERSION.." interpreter by Reuh.") + :epilog "For more info, see https://github.com/Reuh/candran" + +parser:argument("filename", "Candran file to run. Use - to read from standard input. Start the REPL if no filename given.") + :args "?" + +util.cli.addCandranOptions(parser) + +local args = parser:parse() + +local options = util.cli.makeCandranOptions(args) + +-- Run -- -- stdin -if arg[#arg] == "-" then - local f, err = candran.load(io.read("*a"), "stdin", nil, args) +if args.filename == "-" then + local f, err = candran.load(io.read("*a"), "stdin", nil, options) if not f then io.stderr:write("can: "..err.."\n") os.exit(1) @@ -33,8 +35,8 @@ if arg[#arg] == "-" then os.exit(1) end -- file -elseif #args >= 1 then - local f, err = candran.loadfile(args[1], nil, args) +elseif args.filename then + local f, err = candran.loadfile(args.filename, nil, options) if not f then io.stderr:write("can: "..err.."\n") os.exit(1) @@ -47,6 +49,8 @@ elseif #args >= 1 then end -- REPL else + candran.default = util.merge(candran.default, options) + -- Setup linenoise local s, l = pcall(require, "linenoise") if not s then -- pure Lua compatibility thingy diff --git a/bin/canc b/bin/canc index 32265ef..35fb36c 100644 --- a/bin/canc +++ b/bin/canc @@ -1,48 +1,63 @@ #!/usr/bin/env lua local candran = require("candran") -local cmdline = require("candran.cmdline") local parse = require("candran.can-parser.parser").parse local pp = require("candran.can-parser.pp") +local util = require("candran.util") +local argparse = require("argparse") -local args = cmdline(arg) +-- Parse args -- -if #arg < 1 or args.help or args.h then - print("Candran "..candran.VERSION.." compiler by Reuh") - print("Usage: "..arg[0].." [options] filenames...") - print("Use - instead of filenames to read from the standard input. The output file will be named stdin.lua by default.") - print("Compiler options:") - print(" dest=\"directory\" where compiled files should be written") - print(" out=\"name.lua\" output filename. By default, will use the same name as the input file with a .lua extension.") - print(" -print write to the standard output instead of creating files") - print(" -preprocess only run the preprocessor") - print(" -compile only run the compiler") - print(" -parse only parse the file and prints errors to stdout") - print(" -ast (for debugging purposes) only parse the files and dump the AST to stdout") - print(" -help or -h print this text") - print("Default options:") - for opt, val in pairs(candran.default) do - if type(val) == "string" then val = val:gsub("\n", "\\n") end - print((" %s=%q"):format(opt, tostring(val))) - end - return -end +local parser = argparse() + :name "canc" + :description("Candran "..candran.VERSION.." compiler by Reuh.") + :epilog "For more info, see https://github.com/Reuh/candran" -if arg[#arg] == "-" then - table.insert(args, io.stdin) -end +parser:argument("filename", "Candran files to compile. Use - to read from standard input; the output file will then be named stdin.lua by default.") + :args "+" -for _, file in ipairs(args) do +parser:group("Output options", + parser:option("-d --destination") + :description "Where compiled files should be written" + :argname "directory", + + parser:option("-o --output") + :description "Output filename. (default: same name as the input file with a .lua extension)" + :argname "filename", + + parser:flag("-p --print") + :description "Write to the standard output instead of creating files", + + parser:flag("--preprocess") + :description "Only run the preprocessor", + + parser:flag("--compile") + :description "Only run the compiler", + + parser:flag("--parse") + :description "Only parse the file and prints syntax errors to stdout", + + parser:flag("--ast") + :description"(for debugging purposes) Only parse the files and dump the AST to stdout" +) + +util.cli.addCandranOptions(parser) + +local args = parser:parse() + +-- Compile -- + +for _, file in ipairs(args.filename) do -- Read local dest, input - if file == io.stdin then - dest = args.out or "stdin.lua" + if file == "-" then + dest = args.output or "stdin.lua" input = io.read("*a") args.chunkname = "stdin" else - dest = args.out or (file:gsub("%.can$", "")..".lua") + dest = args.output or (file:gsub("%.can$", "")..".lua") local inputFile, err = io.open(file, "r") if not inputFile then @@ -69,8 +84,10 @@ for _, file in ipairs(args) do end -- Compile and output - if args.dest then - dest = args.dest .. "/" .. dest + local options = util.cli.makeCandranOptions(args) + + if args.destination then + dest = args.destination .. "/" .. dest end if not args.print then @@ -79,7 +96,7 @@ for _, file in ipairs(args) do local out = input if args.preprocess then - local r, err = candran.preprocess(out, args) + local r, err = candran.preprocess(out, options) if not r then io.stderr:write("canc: "..err.."\n") os.exit(1) @@ -87,7 +104,7 @@ for _, file in ipairs(args) do out = r end if args.compile then - local r, err = candran.compile(out, args) + local r, err = candran.compile(out, options) if not r then io.stderr:write("canc: "..err.."\n") os.exit(1) @@ -95,7 +112,7 @@ for _, file in ipairs(args) do out = r end if args.compile == nil and args.preprocess == nil then - local r, err = candran.make(input, args) + local r, err = candran.make(input, options) if not r then io.stderr:write("canc: "..err.."\n") os.exit(1) diff --git a/candran.can b/candran.can index 159ac33..3565952 100644 --- a/candran.can +++ b/candran.can @@ -1,5 +1,4 @@ #import("candran.util") -#import("candran.cmdline") #import("candran.serpent") #import("compiler.lua54") @@ -29,7 +28,8 @@ candran.default = { mapLines = true, chunkname = "nil", rewriteErrors = true, - noBuiltInMacros = false + builtInMacros = true, + preprocessorEnv = {} } -- Autodetect version @@ -92,7 +92,7 @@ function candran.preprocess(input, options={}) preprocessor ..= "return output" -- make preprocessor environement - local env = util.merge(_G, options) + local env = util.merge(_G, options.preprocessorEnv) --- Candran library table env.candran = candran --- Current preprocessor output @@ -179,7 +179,7 @@ function candran.preprocess(input, options={}) end -- default macros - if not options.noBuiltInMacros then + if options.builtInMacros then env.define("__STR__(x)", function(x) return ("%q"):format(x) end) local s = require("candran.serpent") env.define("__CONSTEXPR__(expr)", function(expr) diff --git a/candran.lua b/candran.lua index 82260c7..2e961a0 100644 --- a/candran.lua +++ b/candran.lua @@ -1,147 +1,90 @@ local function _() -- candran.can:2 -local util = {} -- ./candran/util.can:1 -util["search"] = function(modpath, exts) -- ./candran/util.can:3 -if exts == nil then exts = {} end -- ./candran/util.can:3 -for _, ext in ipairs(exts) do -- ./candran/util.can:4 -for path in package["path"]:gmatch("[^;]+") do -- ./candran/util.can:5 -local fpath = path:gsub("%.lua", "." .. ext):gsub("%?", (modpath:gsub("%.", "/"))) -- ./candran/util.can:6 -local f = io["open"](fpath) -- ./candran/util.can:7 -if f then -- ./candran/util.can:8 -f:close() -- ./candran/util.can:9 -return fpath -- ./candran/util.can:10 -end -- ./candran/util.can:10 -end -- ./candran/util.can:10 -end -- ./candran/util.can:10 -end -- ./candran/util.can:10 -util["load"] = function(str, name, env) -- ./candran/util.can:16 -if _VERSION == "Lua 5.1" then -- ./candran/util.can:17 -local fn, err = loadstring(str, name) -- ./candran/util.can:18 -if not fn then -- ./candran/util.can:19 -return fn, err -- ./candran/util.can:19 -end -- ./candran/util.can:19 -return env ~= nil and setfenv(fn, env) or fn -- ./candran/util.can:20 -else -- ./candran/util.can:20 -if env then -- ./candran/util.can:22 -return load(str, name, nil, env) -- ./candran/util.can:23 -else -- ./candran/util.can:23 -return load(str, name) -- ./candran/util.can:25 -end -- ./candran/util.can:25 -end -- ./candran/util.can:25 -end -- ./candran/util.can:25 -util["recmerge"] = function(...) -- ./candran/util.can:30 -local r = {} -- ./candran/util.can:31 -for _, t in ipairs({ ... }) do -- ./candran/util.can:32 -for k, v in pairs(t) do -- ./candran/util.can:33 -if type(v) == "table" then -- ./candran/util.can:34 -r[k] = util["merge"](v, r[k]) -- ./candran/util.can:35 -else -- ./candran/util.can:35 -r[k] = v -- ./candran/util.can:37 -end -- ./candran/util.can:37 -end -- ./candran/util.can:37 -end -- ./candran/util.can:37 -return r -- ./candran/util.can:41 -end -- ./candran/util.can:41 -util["merge"] = function(...) -- ./candran/util.can:44 -local r = {} -- ./candran/util.can:45 -for _, t in ipairs({ ... }) do -- ./candran/util.can:46 -for k, v in pairs(t) do -- ./candran/util.can:47 -r[k] = v -- ./candran/util.can:48 -end -- ./candran/util.can:48 -end -- ./candran/util.can:48 -return r -- ./candran/util.can:51 -end -- ./candran/util.can:51 -return util -- ./candran/util.can:54 -end -- ./candran/util.can:54 -local util = _() or util -- ./candran/util.can:58 -package["loaded"]["candran.util"] = util or true -- ./candran/util.can:59 -local function _() -- ./candran/util.can:62 -local ipairs, pairs, setfenv, tonumber, loadstring, type = ipairs, pairs, setfenv, tonumber, loadstring, type -- ./candran/cmdline.lua:5 -local tinsert, tconcat = table["insert"], table["concat"] -- ./candran/cmdline.lua:6 -local function commonerror(msg) -- ./candran/cmdline.lua:8 -return nil, ("[cmdline]: " .. msg) -- ./candran/cmdline.lua:9 -end -- ./candran/cmdline.lua:9 -local function argerror(msg, numarg) -- ./candran/cmdline.lua:12 -msg = msg and (": " .. msg) or "" -- ./candran/cmdline.lua:13 -return nil, ("[cmdline]: bad argument #" .. numarg .. msg) -- ./candran/cmdline.lua:14 -end -- ./candran/cmdline.lua:14 -local function iderror(numarg) -- ./candran/cmdline.lua:17 -return argerror("ID not valid", numarg) -- ./candran/cmdline.lua:18 -end -- ./candran/cmdline.lua:18 -local function idcheck(id) -- ./candran/cmdline.lua:21 -return id:match("^[%a_][%w_]*$") and true -- ./candran/cmdline.lua:22 -end -- ./candran/cmdline.lua:22 -return function(t_in, options, params) -- ./candran/cmdline.lua:73 -local t_out = {} -- ./candran/cmdline.lua:74 -for i, v in ipairs(t_in) do -- ./candran/cmdline.lua:75 -local prefix, command = v:sub(1, 1), v:sub(2) -- ./candran/cmdline.lua:76 -if prefix == "$" then -- ./candran/cmdline.lua:77 -tinsert(t_out, command) -- ./candran/cmdline.lua:78 -elseif prefix == "-" then -- ./candran/cmdline.lua:79 -for id in command:gmatch("[^,;]+") do -- ./candran/cmdline.lua:80 -if not idcheck(id) then -- ./candran/cmdline.lua:81 -return iderror(i) -- ./candran/cmdline.lua:81 -end -- ./candran/cmdline.lua:81 -t_out[id] = true -- ./candran/cmdline.lua:82 -end -- ./candran/cmdline.lua:82 -elseif prefix == "!" then -- ./candran/cmdline.lua:84 -local f, err = loadstring(command) -- ./candran/cmdline.lua:85 -if not f then -- ./candran/cmdline.lua:86 -return argerror(err, i) -- ./candran/cmdline.lua:86 -end -- ./candran/cmdline.lua:86 -setfenv(f, t_out)() -- ./candran/cmdline.lua:87 -elseif v:find("=") then -- ./candran/cmdline.lua:88 -local ids, val = v:match("^([^=]+)%=(.*)") -- ./candran/cmdline.lua:89 -if not ids then -- ./candran/cmdline.lua:90 -return argerror("invalid assignment syntax", i) -- ./candran/cmdline.lua:90 -end -- ./candran/cmdline.lua:90 -if val == "false" then -- ./candran/cmdline.lua:91 -val = false -- ./candran/cmdline.lua:92 -elseif val == "true" then -- ./candran/cmdline.lua:93 -val = true -- ./candran/cmdline.lua:94 -else -- ./candran/cmdline.lua:94 -val = val:sub(1, 1) == "$" and val:sub(2) or tonumber(val) or val -- ./candran/cmdline.lua:96 -end -- ./candran/cmdline.lua:96 -for id in ids:gmatch("[^,;]+") do -- ./candran/cmdline.lua:98 -if not idcheck(id) then -- ./candran/cmdline.lua:99 -return iderror(i) -- ./candran/cmdline.lua:99 -end -- ./candran/cmdline.lua:99 -t_out[id] = val -- ./candran/cmdline.lua:100 -end -- ./candran/cmdline.lua:100 -else -- ./candran/cmdline.lua:100 -tinsert(t_out, v) -- ./candran/cmdline.lua:103 -end -- ./candran/cmdline.lua:103 -end -- ./candran/cmdline.lua:103 -if options then -- ./candran/cmdline.lua:106 -local lookup, unknown = {}, {} -- ./candran/cmdline.lua:107 -for _, v in ipairs(options) do -- ./candran/cmdline.lua:108 -lookup[v] = true -- ./candran/cmdline.lua:108 -end -- ./candran/cmdline.lua:108 -for k, _ in pairs(t_out) do -- ./candran/cmdline.lua:109 -if lookup[k] == nil and type(k) == "string" then -- ./candran/cmdline.lua:110 -tinsert(unknown, k) -- ./candran/cmdline.lua:110 -end -- ./candran/cmdline.lua:110 -end -- ./candran/cmdline.lua:110 -if # unknown > 0 then -- ./candran/cmdline.lua:112 -return commonerror("unknown options: " .. tconcat(unknown, ", ")) -- ./candran/cmdline.lua:113 -end -- ./candran/cmdline.lua:113 -end -- ./candran/cmdline.lua:113 -if params then -- ./candran/cmdline.lua:116 -local missing = {} -- ./candran/cmdline.lua:117 -for _, v in ipairs(params) do -- ./candran/cmdline.lua:118 -if t_out[v] == nil then -- ./candran/cmdline.lua:119 -tinsert(missing, v) -- ./candran/cmdline.lua:119 -end -- ./candran/cmdline.lua:119 -end -- ./candran/cmdline.lua:119 -if # missing > 0 then -- ./candran/cmdline.lua:121 -return commonerror("missing parameters: " .. tconcat(missing, ", ")) -- ./candran/cmdline.lua:122 -end -- ./candran/cmdline.lua:122 -end -- ./candran/cmdline.lua:122 -return t_out -- ./candran/cmdline.lua:125 -end -- ./candran/cmdline.lua:125 -end -- ./candran/cmdline.lua:125 -local cmdline = _() or cmdline -- ./candran/cmdline.lua:130 -package["loaded"]["candran.cmdline"] = cmdline or true -- ./candran/cmdline.lua:131 -local function _() -- ./candran/cmdline.lua:134 +local candran = require("candran") -- ./candran/util.can:1 +local util = {} -- ./candran/util.can:2 +util["search"] = function(modpath, exts) -- ./candran/util.can:4 +if exts == nil then exts = {} end -- ./candran/util.can:4 +for _, ext in ipairs(exts) do -- ./candran/util.can:5 +for path in package["path"]:gmatch("[^;]+") do -- ./candran/util.can:6 +local fpath = path:gsub("%.lua", "." .. ext):gsub("%?", (modpath:gsub("%.", "/"))) -- ./candran/util.can:7 +local f = io["open"](fpath) -- ./candran/util.can:8 +if f then -- ./candran/util.can:9 +f:close() -- ./candran/util.can:10 +return fpath -- ./candran/util.can:11 +end -- ./candran/util.can:11 +end -- ./candran/util.can:11 +end -- ./candran/util.can:11 +end -- ./candran/util.can:11 +util["load"] = function(str, name, env) -- ./candran/util.can:17 +if _VERSION == "Lua 5.1" then -- ./candran/util.can:18 +local fn, err = loadstring(str, name) -- ./candran/util.can:19 +if not fn then -- ./candran/util.can:20 +return fn, err -- ./candran/util.can:20 +end -- ./candran/util.can:20 +return env ~= nil and setfenv(fn, env) or fn -- ./candran/util.can:21 +else -- ./candran/util.can:21 +if env then -- ./candran/util.can:23 +return load(str, name, nil, env) -- ./candran/util.can:24 +else -- ./candran/util.can:24 +return load(str, name) -- ./candran/util.can:26 +end -- ./candran/util.can:26 +end -- ./candran/util.can:26 +end -- ./candran/util.can:26 +util["recmerge"] = function(...) -- ./candran/util.can:31 +local r = {} -- ./candran/util.can:32 +for _, t in ipairs({ ... }) do -- ./candran/util.can:33 +for k, v in pairs(t) do -- ./candran/util.can:34 +if type(v) == "table" then -- ./candran/util.can:35 +r[k] = util["merge"](v, r[k]) -- ./candran/util.can:36 +else -- ./candran/util.can:36 +r[k] = v -- ./candran/util.can:38 +end -- ./candran/util.can:38 +end -- ./candran/util.can:38 +end -- ./candran/util.can:38 +return r -- ./candran/util.can:42 +end -- ./candran/util.can:42 +util["merge"] = function(...) -- ./candran/util.can:45 +local r = {} -- ./candran/util.can:46 +for _, t in ipairs({ ... }) do -- ./candran/util.can:47 +for k, v in pairs(t) do -- ./candran/util.can:48 +r[k] = v -- ./candran/util.can:49 +end -- ./candran/util.can:49 +end -- ./candran/util.can:49 +return r -- ./candran/util.can:52 +end -- ./candran/util.can:52 +util["cli"] = { -- ./candran/util.can:55 +["addCandranOptions"] = function(parser) -- ./candran/util.can:57 +parser:group("Compiler options", parser:option("-t --target"):description("Target Lua version: lua54, lua53, lua52, luajit or lua51"):default(candran["default"]["target"]), parser:option("--indentation"):description("Character(s) used for indentation in the compiled file"):default(candran["default"]["indentation"]), parser:option("--newline"):description("Character(s) used for newlines in the compiled file"):default(candran["default"]["newline"]), parser:option("--variable-prefix"):description("Prefix used when Candran needs to set a local variable to provide some functionality"):default(candran["default"]["variablePrefix"]), parser:flag("--no-map-lines"):description("Do not add comments at the end of each line indicating the associated source line and file (error rewriting will not work)")) -- ./candran/util.can:76 +parser:group("Preprocessor options", parser:flag("--no-builtin-macros"):description("Disable built-in macros"), parser:option("-D --define"):description("Define a preprocessor constant"):args("1-2"):argname({ -- ./candran/util.can:86 +"name", -- ./candran/util.can:86 +"value" -- ./candran/util.can:86 +}):count("*")) -- ./candran/util.can:87 +parser:option("--chunkname"):description("Chunkname used when running the code") -- ./candran/util.can:91 +parser:flag("--no-rewrite-errors"):description("Disable error rewriting when running the code") -- ./candran/util.can:94 +end, -- ./candran/util.can:94 +["makeCandranOptions"] = function(args) -- ./candran/util.can:98 +local preprocessorEnv = {} -- ./candran/util.can:99 +for _, o in ipairs(args["define"]) do -- ./candran/util.can:100 +preprocessorEnv[o[1]] = tonumber(o[2]) or o[2] or true -- ./candran/util.can:101 +end -- ./candran/util.can:101 +local options = { -- ./candran/util.can:104 +["target"] = args["target"], -- ./candran/util.can:105 +["indentation"] = args["indentation"], -- ./candran/util.can:106 +["newline"] = args["newline"], -- ./candran/util.can:107 +["variablePrefix"] = args["variable_prefix"], -- ./candran/util.can:108 +["mapLines"] = not args["no_map_lines"], -- ./candran/util.can:109 +["chunkname"] = args["chunkname"], -- ./candran/util.can:110 +["rewriteErrors"] = not args["no_rewrite_errors"], -- ./candran/util.can:111 +["builtInMacros"] = not args["no_builtin_macros"], -- ./candran/util.can:112 +["preprocessorEnv"] = preprocessorEnv -- ./candran/util.can:113 +} -- ./candran/util.can:113 +return options -- ./candran/util.can:115 +end -- ./candran/util.can:115 +} -- ./candran/util.can:115 +return util -- ./candran/util.can:119 +end -- ./candran/util.can:119 +local util = _() or util -- ./candran/util.can:123 +package["loaded"]["candran.util"] = util or true -- ./candran/util.can:124 +local function _() -- ./candran/util.can:127 local n, v = "serpent", "0.302" -- ./candran/serpent.lua:24 local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" -- ./candran/serpent.lua:25 local snum = { -- ./candran/serpent.lua:26 @@ -7067,19 +7010,20 @@ return parser -- ./candran/can-parser/parser.lua:807 end -- ./candran/can-parser/parser.lua:807 local parser = _() or parser -- ./candran/can-parser/parser.lua:811 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:812 -local unpack = unpack or table["unpack"] -- candran.can:16 -local candran = { ["VERSION"] = "0.14.0" } -- candran.can:19 -package["loaded"]["candran"] = candran -- candran.can:21 -candran["default"] = { -- candran.can:24 -["target"] = "lua54", -- candran.can:25 -["indentation"] = "", -- candran.can:26 +local unpack = unpack or table["unpack"] -- candran.can:15 +local candran = { ["VERSION"] = "0.14.0" } -- candran.can:18 +package["loaded"]["candran"] = candran -- candran.can:20 +candran["default"] = { -- candran.can:23 +["target"] = "lua54", -- candran.can:24 +["indentation"] = "", -- candran.can:25 ["newline"] = "\ -", -- candran.can:27 -["variablePrefix"] = "__CAN_", -- candran.can:28 -["mapLines"] = true, -- candran.can:29 -["chunkname"] = "nil", -- candran.can:30 -["rewriteErrors"] = true, -- candran.can:31 -["noBuiltInMacros"] = false -- candran.can:32 +", -- candran.can:26 +["variablePrefix"] = "__CAN_", -- candran.can:27 +["mapLines"] = true, -- candran.can:28 +["chunkname"] = "nil", -- candran.can:29 +["rewriteErrors"] = true, -- candran.can:30 +["builtInMacros"] = true, -- candran.can:31 +["preprocessorEnv"] = {} -- candran.can:32 } -- candran.can:32 if _VERSION == "Lua 5.1" then -- candran.can:36 if package["loaded"]["jit"] then -- candran.can:37 @@ -7132,7 +7076,7 @@ end -- candran.can:88 end -- candran.can:88 end -- candran.can:88 preprocessor = preprocessor .. ("return output") -- candran.can:92 -local env = util["merge"](_G, options) -- candran.can:95 +local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:95 env["candran"] = candran -- candran.can:97 env["output"] = "" -- candran.can:99 env["import"] = function(modpath, margs) -- candran.can:106 @@ -7207,7 +7151,7 @@ else -- candran.can:175 error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:177 end -- candran.can:177 end -- candran.can:177 -if not options["noBuiltInMacros"] then -- candran.can:182 +if options["builtInMacros"] then -- candran.can:182 env["define"]("__STR__(x)", function(x) -- candran.can:183 return ("%q"):format(x) -- candran.can:183 end) -- candran.can:183 diff --git a/candran/cmdline.lua b/candran/cmdline.lua deleted file mode 100644 index c27e0f9..0000000 --- a/candran/cmdline.lua +++ /dev/null @@ -1,126 +0,0 @@ --- started: 2008-04-12 by Shmuel Zeigerman --- license: public domain - -local ipairs,pairs,setfenv,tonumber,loadstring,type = - ipairs,pairs,setfenv,tonumber,loadstring,type -local tinsert, tconcat = table.insert, table.concat - -local function commonerror (msg) - return nil, ("[cmdline]: " .. msg) -end - -local function argerror (msg, numarg) - msg = msg and (": " .. msg) or "" - return nil, ("[cmdline]: bad argument #" .. numarg .. msg) -end - -local function iderror (numarg) - return argerror("ID not valid", numarg) -end - -local function idcheck (id) - return id:match("^[%a_][%w_]*$") and true -end - ---[[------------------------------------------------------------------------ -Syntax: - t_out = getparam(t_in [,options] [,params]) - -Parameters: - t_in: table - list of string arguments to be processed in order - (usually it is the `arg' table created by the Lua interpreter). - - * if an argument begins with $, the $ is skipped and the rest is inserted - into the array part of the output table. - - * if an argument begins with -, the rest is a sequence of variables - (separated by commas or semicolons) that are all set to true; - example: -var1,var2 --> var1,var2 = true,true - - * if an argument begins with !, the rest is a Lua chunk; - example: !a=(40+3)*5;b=20;name="John";window={w=600,h=480} - - * if an argument contains =, then it is an assignment in the form - var1,...=value (no space is allowed around the =) - * if value begins with $, the $ is skipped, the rest is a string - example: var1,var2=$ --> var1,var2 = "","" - example: var1,var2=$125 --> var1,var2 = "125","125" - example: var1,var2=$$125 --> var1,var2 = "$125","$125" - * if value is convertible to number, it is a number - example: var1,var2=125 --> var1,var2 = 125,125 - * if value is true of false, it is a boolean - example: var1=false --> var1 = false - * otherwise it is a string - example: name=John --> name = "John" - - * if an argument neither begins with one of the special characters (-,!,$), - nor contains =, it is inserted as is into the array part of the output - table. - - options (optional): a list of names of all command-line options and parameters - permitted in the application; used to check that each found option - is valid; no checks are done if not supplied. - - params (optional): a list of names of all command-line parameters required - by the application; used to check that each required parameter is present; - no checks are done if not supplied. - -Returns: - On success: the output table, e.g. { [1]="./myfile.txt", name="John", age=40 } - On error: nil followed by error message string. - ---]]------------------------------------------------------------------------ -return function(t_in, options, params) - local t_out = {} - for i,v in ipairs(t_in) do - local prefix, command = v:sub(1,1), v:sub(2) - if prefix == "$" then - tinsert(t_out, command) - elseif prefix == "-" then - for id in command:gmatch"[^,;]+" do - if not idcheck(id) then return iderror(i) end - t_out[id] = true - end - elseif prefix == "!" then - local f, err = loadstring(command) - if not f then return argerror(err, i) end - setfenv(f, t_out)() - elseif v:find("=") then - local ids, val = v:match("^([^=]+)%=(.*)") -- no space around = - if not ids then return argerror("invalid assignment syntax", i) end - if val == "false" then - val = false - elseif val == "true" then - val = true - else - val = val:sub(1,1)=="$" and val:sub(2) or tonumber(val) or val - end - for id in ids:gmatch"[^,;]+" do - if not idcheck(id) then return iderror(i) end - t_out[id] = val - end - else - tinsert(t_out, v) - end - end - if options then - local lookup, unknown = {}, {} - for _,v in ipairs(options) do lookup[v] = true end - for k,_ in pairs(t_out) do - if lookup[k]==nil and type(k)=="string" then tinsert(unknown, k) end - end - if #unknown > 0 then - return commonerror("unknown options: " .. tconcat(unknown, ", ")) - end - end - if params then - local missing = {} - for _,v in ipairs(params) do - if t_out[v]==nil then tinsert(missing, v) end - end - if #missing > 0 then - return commonerror("missing parameters: " .. tconcat(missing, ", ")) - end - end - return t_out -end diff --git a/candran/util.can b/candran/util.can index c03689b..faf4a69 100644 --- a/candran/util.can +++ b/candran/util.can @@ -1,3 +1,4 @@ +local candran = require("candran") local util = {} function util.search(modpath, exts={}) @@ -51,4 +52,68 @@ function util.merge(...) return r end +util.cli = { + -- add option to set Candran options to an argparse parser + addCandranOptions = function(parser) + parser:group("Compiler options", + parser:option("-t --target") + :description "Target Lua version: lua54, lua53, lua52, luajit or lua51" + :default(candran.default.target), + + parser:option("--indentation") + :description "Character(s) used for indentation in the compiled file" + :default(candran.default.indentation), + + parser:option("--newline") + :description "Character(s) used for newlines in the compiled file" + :default(candran.default.newline), + + parser:option("--variable-prefix") + :description "Prefix used when Candran needs to set a local variable to provide some functionality" + :default(candran.default.variablePrefix), + + parser:flag("--no-map-lines") + :description "Do not add comments at the end of each line indicating the associated source line and file (error rewriting will not work)" + ) + + parser:group("Preprocessor options", + parser:flag("--no-builtin-macros") + :description "Disable built-in macros", + + parser:option("-D --define") + :description "Define a preprocessor constant" + :args("1-2") + :argname{"name", "value"} + :count("*") + ) + + parser:option("--chunkname") + :description "Chunkname used when running the code" + + parser:flag("--no-rewrite-errors") + :description "Disable error rewriting when running the code" + end, + + -- convert parsed arguments to a Candran options table + makeCandranOptions = function(args) + local preprocessorEnv = {} + for _, o in ipairs(args.define) do + preprocessorEnv[o[1]] = tonumber(o[2]) or o[2] or true + end + + local options = { + target = args.target, + indentation = args.indentation, + newline = args.newline, + variablePrefix = args.variable_prefix, + mapLines = not args.no_map_lines, + chunkname = args.chunkname, + rewriteErrors = not args.no_rewrite_errors, + builtInMacros = not args.no_builtin_macros, + preprocessorEnv = preprocessorEnv + } + return options + end +} + return util diff --git a/rockspec/candran-scm-1.rockspec b/rockspec/candran-scm-1.rockspec index c6573dd..71ce00b 100644 --- a/rockspec/candran-scm-1.rockspec +++ b/rockspec/candran-scm-1.rockspec @@ -18,14 +18,16 @@ description = { } source = { - url = "git://github.com/Reuh/candran" + url = "git://github.com/Reuh/candran", + branch = "argparse" } dependencies = { "lua >= 5.1", "lpeglabel >= 1.5.0", "linenoise >= 0.9", - "luacheck >= 0.23.0" + "luacheck >= 0.23.0", + "argparse >= 0.7.0" } build = { From ff6d7f8febb79c7f17725d4771314f508d25ee80 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 17 Jun 2021 19:47:07 +0200 Subject: [PATCH 41/52] Fix require cycle --- candran.can | 10 +++++----- candran.lua | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/candran.can b/candran.can index 3565952..b967ac0 100644 --- a/candran.can +++ b/candran.can @@ -1,3 +1,8 @@ +local candran = { + VERSION = "0.14.0" +} +package.loaded["candran"] = candran + #import("candran.util") #import("candran.serpent") @@ -14,11 +19,6 @@ local unpack = unpack or table.unpack -local candran = { - VERSION = "0.14.0" -} -package.loaded["candran"] = candran - --- Default options. candran.default = { target = "lua54", diff --git a/candran.lua b/candran.lua index 2e961a0..52a71a6 100644 --- a/candran.lua +++ b/candran.lua @@ -1,4 +1,6 @@ -local function _() -- candran.can:2 +local candran = { ["VERSION"] = "0.14.0" } -- candran.can:2 +package["loaded"]["candran"] = candran -- candran.can:4 +local function _() -- candran.can:7 local candran = require("candran") -- ./candran/util.can:1 local util = {} -- ./candran/util.can:2 util["search"] = function(modpath, exts) -- ./candran/util.can:4 @@ -7010,9 +7012,7 @@ return parser -- ./candran/can-parser/parser.lua:807 end -- ./candran/can-parser/parser.lua:807 local parser = _() or parser -- ./candran/can-parser/parser.lua:811 package["loaded"]["candran.can-parser.parser"] = parser or true -- ./candran/can-parser/parser.lua:812 -local unpack = unpack or table["unpack"] -- candran.can:15 -local candran = { ["VERSION"] = "0.14.0" } -- candran.can:18 -package["loaded"]["candran"] = candran -- candran.can:20 +local unpack = unpack or table["unpack"] -- candran.can:20 candran["default"] = { -- candran.can:23 ["target"] = "lua54", -- candran.can:24 ["indentation"] = "", -- candran.can:25 From 01e808e2e65155a0609f4c81f0eb2d53b540cdf5 Mon Sep 17 00:00:00 2001 From: Reuh Date: Thu, 17 Jun 2021 20:18:38 +0200 Subject: [PATCH 42/52] Fix Lua < 5.4 compiler with new preprocessor env --- compiler/lua51.can | 2 +- compiler/lua52.can | 2 +- compiler/lua53.can | 2 +- compiler/luajit.can | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/lua51.can b/compiler/lua51.can index 9443454..61b07a5 100644 --- a/compiler/lua51.can +++ b/compiler/lua51.can @@ -33,6 +33,6 @@ end #local patch = output #output = "" -#import("compiler.luajit", { patch = patch, loadPackage = false }) +#import("compiler.luajit", { preprocessorEnv = { patch = patch }, loadPackage = false }) return luajit diff --git a/compiler/lua52.can b/compiler/lua52.can index 7f94efc..d42c3a8 100644 --- a/compiler/lua52.can +++ b/compiler/lua52.can @@ -30,6 +30,6 @@ end #local patch = output #output = "" -#import("compiler.lua53", { patch = patch, loadPackage = false }) +#import("compiler.lua53", { preprocessorEnv = { patch = patch }, loadPackage = false }) return lua53 diff --git a/compiler/lua53.can b/compiler/lua53.can index 582fa69..ab354f7 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -13,6 +13,6 @@ end #local patch = output #output = "" -#import("compiler.lua54", { patch = patch, loadPackage = false }) +#import("compiler.lua54", { preprocessorEnv = { patch = patch }, loadPackage = false }) return lua54 diff --git a/compiler/luajit.can b/compiler/luajit.can index 511f642..83def13 100644 --- a/compiler/luajit.can +++ b/compiler/luajit.can @@ -33,6 +33,6 @@ end #local patch = output #output = "" -#import("compiler.lua52", { patch = patch, loadPackage = false }) +#import("compiler.lua52", { preprocessorEnv = { patch = patch }, loadPackage = false }) return lua52 From 008e7732bc85aeba425cd6fd217b40901d680f78 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 14:01:27 +0200 Subject: [PATCH 43/52] Add static import --- bin/can | 1 + candran.can | 9 +- candran.lua | 629 ++++++++++++++++++++++++----------------------- candran/util.can | 8 +- 4 files changed, 334 insertions(+), 313 deletions(-) diff --git a/bin/can b/bin/can index 3ab0f36..903dea2 100644 --- a/bin/can +++ b/bin/can @@ -3,6 +3,7 @@ local candran = require("candran").setup() local util = require("candran.util") local argparse = require("argparse") +local unpack = unpack or table.unpack -- Parse args -- diff --git a/candran.can b/candran.can index b967ac0..4e90067 100644 --- a/candran.can +++ b/candran.can @@ -29,7 +29,8 @@ candran.default = { chunkname = "nil", rewriteErrors = true, builtInMacros = true, - preprocessorEnv = {} + preprocessorEnv = {}, + import = {} } -- Autodetect version @@ -59,6 +60,11 @@ function candran.preprocess(input, options={}) variables = {} } + -- add auto imports + for _, mod in ipairs(options.import) do + input =.. "#import(%q, {loadLocal=false})\n":format(mod) + end + -- generate preprocessor code local preprocessor = "" local i = 0 @@ -111,6 +117,7 @@ function candran.preprocess(input, options={}) if not f then error("can't open the module file to import") end margs = util.merge(options, { chunkname = filepath, loadLocal = true, loadPackage = true }, margs) + margs.import = {} -- no need for recursive import local modcontent, modmacros = assert(candran.preprocess(f:read("*a"), margs)) macros = util.recmerge(macros, modmacros) f:close() diff --git a/candran.lua b/candran.lua index 52a71a6..8ea8eb7 100644 --- a/candran.lua +++ b/candran.lua @@ -59,34 +59,35 @@ parser:group("Compiler options", parser:option("-t --target"):description("Targe parser:group("Preprocessor options", parser:flag("--no-builtin-macros"):description("Disable built-in macros"), parser:option("-D --define"):description("Define a preprocessor constant"):args("1-2"):argname({ -- ./candran/util.can:86 "name", -- ./candran/util.can:86 "value" -- ./candran/util.can:86 -}):count("*")) -- ./candran/util.can:87 -parser:option("--chunkname"):description("Chunkname used when running the code") -- ./candran/util.can:91 -parser:flag("--no-rewrite-errors"):description("Disable error rewriting when running the code") -- ./candran/util.can:94 -end, -- ./candran/util.can:94 -["makeCandranOptions"] = function(args) -- ./candran/util.can:98 -local preprocessorEnv = {} -- ./candran/util.can:99 -for _, o in ipairs(args["define"]) do -- ./candran/util.can:100 -preprocessorEnv[o[1]] = tonumber(o[2]) or o[2] or true -- ./candran/util.can:101 -end -- ./candran/util.can:101 -local options = { -- ./candran/util.can:104 -["target"] = args["target"], -- ./candran/util.can:105 -["indentation"] = args["indentation"], -- ./candran/util.can:106 -["newline"] = args["newline"], -- ./candran/util.can:107 -["variablePrefix"] = args["variable_prefix"], -- ./candran/util.can:108 -["mapLines"] = not args["no_map_lines"], -- ./candran/util.can:109 -["chunkname"] = args["chunkname"], -- ./candran/util.can:110 -["rewriteErrors"] = not args["no_rewrite_errors"], -- ./candran/util.can:111 -["builtInMacros"] = not args["no_builtin_macros"], -- ./candran/util.can:112 -["preprocessorEnv"] = preprocessorEnv -- ./candran/util.can:113 -} -- ./candran/util.can:113 -return options -- ./candran/util.can:115 -end -- ./candran/util.can:115 -} -- ./candran/util.can:115 -return util -- ./candran/util.can:119 -end -- ./candran/util.can:119 -local util = _() or util -- ./candran/util.can:123 -package["loaded"]["candran.util"] = util or true -- ./candran/util.can:124 -local function _() -- ./candran/util.can:127 +}):count("*"), parser:option("-I --import"):description("Statically import a module into the compiled file"):argname("module"):count("*")) -- ./candran/util.can:92 +parser:option("--chunkname"):description("Chunkname used when running the code") -- ./candran/util.can:96 +parser:flag("--no-rewrite-errors"):description("Disable error rewriting when running the code") -- ./candran/util.can:99 +end, -- ./candran/util.can:99 +["makeCandranOptions"] = function(args) -- ./candran/util.can:103 +local preprocessorEnv = {} -- ./candran/util.can:104 +for _, o in ipairs(args["define"]) do -- ./candran/util.can:105 +preprocessorEnv[o[1]] = tonumber(o[2]) or o[2] or true -- ./candran/util.can:106 +end -- ./candran/util.can:106 +local options = { -- ./candran/util.can:109 +["target"] = args["target"], -- ./candran/util.can:110 +["indentation"] = args["indentation"], -- ./candran/util.can:111 +["newline"] = args["newline"], -- ./candran/util.can:112 +["variablePrefix"] = args["variable_prefix"], -- ./candran/util.can:113 +["mapLines"] = not args["no_map_lines"], -- ./candran/util.can:114 +["chunkname"] = args["chunkname"], -- ./candran/util.can:115 +["rewriteErrors"] = not args["no_rewrite_errors"], -- ./candran/util.can:116 +["builtInMacros"] = not args["no_builtin_macros"], -- ./candran/util.can:117 +["preprocessorEnv"] = preprocessorEnv, -- ./candran/util.can:118 +["import"] = args["import"] -- ./candran/util.can:119 +} -- ./candran/util.can:119 +return options -- ./candran/util.can:121 +end -- ./candran/util.can:121 +} -- ./candran/util.can:121 +return util -- ./candran/util.can:125 +end -- ./candran/util.can:125 +local util = _() or util -- ./candran/util.can:129 +package["loaded"]["candran.util"] = util or true -- ./candran/util.can:130 +local function _() -- ./candran/util.can:133 local n, v = "serpent", "0.302" -- ./candran/serpent.lua:24 local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" -- ./candran/serpent.lua:25 local snum = { -- ./candran/serpent.lua:26 @@ -7023,309 +7024,315 @@ candran["default"] = { -- candran.can:23 ["chunkname"] = "nil", -- candran.can:29 ["rewriteErrors"] = true, -- candran.can:30 ["builtInMacros"] = true, -- candran.can:31 -["preprocessorEnv"] = {} -- candran.can:32 -} -- candran.can:32 -if _VERSION == "Lua 5.1" then -- candran.can:36 -if package["loaded"]["jit"] then -- candran.can:37 -candran["default"]["target"] = "luajit" -- candran.can:38 -else -- candran.can:38 -candran["default"]["target"] = "lua51" -- candran.can:40 -end -- candran.can:40 -elseif _VERSION == "Lua 5.2" then -- candran.can:42 -candran["default"]["target"] = "lua52" -- candran.can:43 -elseif _VERSION == "Lua 5.3" then -- candran.can:44 -candran["default"]["target"] = "lua53" -- candran.can:45 -end -- candran.can:45 -candran["preprocess"] = function(input, options) -- candran.can:55 -if options == nil then options = {} end -- candran.can:55 -options = util["merge"](candran["default"], options) -- candran.can:56 -local macros = { -- candran.can:57 -["functions"] = {}, -- candran.can:58 -["variables"] = {} -- candran.can:59 -} -- candran.can:59 -local preprocessor = "" -- candran.can:63 -local i = 0 -- candran.can:64 -local inLongString = false -- candran.can:65 -local inComment = false -- candran.can:66 +["preprocessorEnv"] = {}, -- candran.can:32 +["import"] = {} -- candran.can:33 +} -- candran.can:33 +if _VERSION == "Lua 5.1" then -- candran.can:37 +if package["loaded"]["jit"] then -- candran.can:38 +candran["default"]["target"] = "luajit" -- candran.can:39 +else -- candran.can:39 +candran["default"]["target"] = "lua51" -- candran.can:41 +end -- candran.can:41 +elseif _VERSION == "Lua 5.2" then -- candran.can:43 +candran["default"]["target"] = "lua52" -- candran.can:44 +elseif _VERSION == "Lua 5.3" then -- candran.can:45 +candran["default"]["target"] = "lua53" -- candran.can:46 +end -- candran.can:46 +candran["preprocess"] = function(input, options) -- candran.can:56 +if options == nil then options = {} end -- candran.can:56 +options = util["merge"](candran["default"], options) -- candran.can:57 +local macros = { -- candran.can:58 +["functions"] = {}, -- candran.can:59 +["variables"] = {} -- candran.can:60 +} -- candran.can:60 +for _, mod in ipairs(options["import"]) do -- candran.can:64 +input = (("#import(%q, {loadLocal=false})\ +"):format(mod)) .. input -- candran.can:65 +end -- candran.can:65 +local preprocessor = "" -- candran.can:69 +local i = 0 -- candran.can:70 +local inLongString = false -- candran.can:71 +local inComment = false -- candran.can:72 for line in (input .. "\ "):gmatch("(.-\ -)") do -- candran.can:67 -i = i + (1) -- candran.can:68 -if inComment then -- candran.can:70 -inComment = not line:match("%]%]") -- candran.can:71 -elseif inLongString then -- candran.can:72 -inLongString = not line:match("%]%]") -- candran.can:73 -else -- candran.can:73 -if line:match("[^%-]%[%[") then -- candran.can:75 -inLongString = true -- candran.can:76 -elseif line:match("%-%-%[%[") then -- candran.can:77 -inComment = true -- candran.can:78 -end -- candran.can:78 -end -- candran.can:78 -if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:81 -preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:82 -else -- candran.can:82 -local l = line:sub(1, - 2) -- candran.can:84 -if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:85 +)") do -- candran.can:73 +i = i + (1) -- candran.can:74 +if inComment then -- candran.can:76 +inComment = not line:match("%]%]") -- candran.can:77 +elseif inLongString then -- candran.can:78 +inLongString = not line:match("%]%]") -- candran.can:79 +else -- candran.can:79 +if line:match("[^%-]%[%[") then -- candran.can:81 +inLongString = true -- candran.can:82 +elseif line:match("%-%-%[%[") then -- candran.can:83 +inComment = true -- candran.can:84 +end -- candran.can:84 +end -- candran.can:84 +if not inComment and not inLongString and line:match("^%s*#") and not line:match("^#!") then -- candran.can:87 +preprocessor = preprocessor .. (line:gsub("^%s*#", "")) -- candran.can:88 +else -- candran.can:88 +local l = line:sub(1, - 2) -- candran.can:90 +if not inLongString and options["mapLines"] and not l:match("%-%- (.-)%:(%d+)$") then -- candran.can:91 preprocessor = preprocessor .. (("write(%q)"):format(l .. " -- " .. options["chunkname"] .. ":" .. i) .. "\ -") -- candran.can:86 -else -- candran.can:86 +") -- candran.can:92 +else -- candran.can:92 preprocessor = preprocessor .. (("write(%q)"):format(line:sub(1, - 2)) .. "\ -") -- candran.can:88 -end -- candran.can:88 -end -- candran.can:88 -end -- candran.can:88 -preprocessor = preprocessor .. ("return output") -- candran.can:92 -local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:95 -env["candran"] = candran -- candran.can:97 -env["output"] = "" -- candran.can:99 -env["import"] = function(modpath, margs) -- candran.can:106 -if margs == nil then margs = {} end -- candran.can:106 -local filepath = assert(util["search"](modpath, { -- candran.can:107 -"can", -- candran.can:107 -"lua" -- candran.can:107 -}), "No module named \"" .. modpath .. "\"") -- candran.can:107 -local f = io["open"](filepath) -- candran.can:110 -if not f then -- candran.can:111 -error("can't open the module file to import") -- candran.can:111 -end -- candran.can:111 -margs = util["merge"](options, { -- candran.can:113 -["chunkname"] = filepath, -- candran.can:113 -["loadLocal"] = true, -- candran.can:113 -["loadPackage"] = true -- candran.can:113 -}, margs) -- candran.can:113 -local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:114 -macros = util["recmerge"](macros, modmacros) -- candran.can:115 -f:close() -- candran.can:116 -local modname = modpath:match("[^%.]+$") -- candran.can:119 +") -- candran.can:94 +end -- candran.can:94 +end -- candran.can:94 +end -- candran.can:94 +preprocessor = preprocessor .. ("return output") -- candran.can:98 +local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:101 +env["candran"] = candran -- candran.can:103 +env["output"] = "" -- candran.can:105 +env["import"] = function(modpath, margs) -- candran.can:112 +if margs == nil then margs = {} end -- candran.can:112 +local filepath = assert(util["search"](modpath, { -- candran.can:113 +"can", -- candran.can:113 +"lua" -- candran.can:113 +}), "No module named \"" .. modpath .. "\"") -- candran.can:113 +local f = io["open"](filepath) -- candran.can:116 +if not f then -- candran.can:117 +error("can't open the module file to import") -- candran.can:117 +end -- candran.can:117 +margs = util["merge"](options, { -- candran.can:119 +["chunkname"] = filepath, -- candran.can:119 +["loadLocal"] = true, -- candran.can:119 +["loadPackage"] = true -- candran.can:119 +}, margs) -- candran.can:119 +margs["import"] = {} -- candran.can:120 +local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:121 +macros = util["recmerge"](macros, modmacros) -- candran.can:122 +f:close() -- candran.can:123 +local modname = modpath:match("[^%.]+$") -- candran.can:126 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:128 -end -- candran.can:128 -env["include"] = function(file) -- candran.can:133 -local f = io["open"](file) -- candran.can:134 -if not f then -- candran.can:135 -error("can't open the file " .. file .. " to include") -- candran.can:135 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:135 end -- candran.can:135 -env["write"](f:read("*a")) -- candran.can:136 -f:close() -- candran.can:137 -end -- candran.can:137 -env["write"] = function(...) -- candran.can:141 -env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:142 +env["include"] = function(file) -- candran.can:140 +local f = io["open"](file) -- candran.can:141 +if not f then -- candran.can:142 +error("can't open the file " .. file .. " to include") -- candran.can:142 end -- candran.can:142 -env["placeholder"] = function(name) -- candran.can:146 -if env[name] then -- candran.can:147 -env["write"](env[name]) -- candran.can:148 -end -- candran.can:148 -end -- candran.can:148 -env["define"] = function(identifier, replacement) -- candran.can:151 -local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:153 -if not iast then -- candran.can:154 -return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:155 +env["write"](f:read("*a")) -- candran.can:143 +f:close() -- candran.can:144 +end -- candran.can:144 +env["write"] = function(...) -- candran.can:148 +env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ +") -- candran.can:149 +end -- candran.can:149 +env["placeholder"] = function(name) -- candran.can:153 +if env[name] then -- candran.can:154 +env["write"](env[name]) -- candran.can:155 end -- candran.can:155 -if type(replacement) == "string" then -- candran.can:158 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:159 -if not rast then -- candran.can:160 -return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:161 -end -- candran.can:161 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:164 -rast = rast[1][1] -- candran.can:165 -end -- candran.can:165 -replacement = rast -- candran.can:167 -elseif type(replacement) ~= "function" then -- candran.can:168 -error("bad argument #2 to 'define' (string or function expected)") -- candran.can:169 -end -- candran.can:169 -if iast["tag"] == "MacroFunction" then -- candran.can:172 -macros["functions"][iast[1][1]] = { -- candran.can:173 -["args"] = iast[2], -- candran.can:173 -["replacement"] = replacement -- candran.can:173 -} -- candran.can:173 -elseif iast["tag"] == "Id" then -- candran.can:174 -macros["variables"][iast[1]] = replacement -- candran.can:175 -else -- candran.can:175 -error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:177 -end -- candran.can:177 -end -- candran.can:177 -if options["builtInMacros"] then -- candran.can:182 -env["define"]("__STR__(x)", function(x) -- candran.can:183 -return ("%q"):format(x) -- candran.can:183 -end) -- candran.can:183 -local s = require("candran.serpent") -- candran.can:184 -env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:185 -return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:186 -end) -- candran.can:186 -end -- candran.can:186 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:191 -if not preprocess then -- candran.can:192 -return nil, "in preprocessor: " .. err -- candran.can:193 +end -- candran.can:155 +env["define"] = function(identifier, replacement) -- candran.can:158 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:160 +if not iast then -- candran.can:161 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:162 +end -- candran.can:162 +if type(replacement) == "string" then -- candran.can:165 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:166 +if not rast then -- candran.can:167 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:168 +end -- candran.can:168 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:171 +rast = rast[1][1] -- candran.can:172 +end -- candran.can:172 +replacement = rast -- candran.can:174 +elseif type(replacement) ~= "function" then -- candran.can:175 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:176 +end -- candran.can:176 +if iast["tag"] == "MacroFunction" then -- candran.can:179 +macros["functions"][iast[1][1]] = { -- candran.can:180 +["args"] = iast[2], -- candran.can:180 +["replacement"] = replacement -- candran.can:180 +} -- candran.can:180 +elseif iast["tag"] == "Id" then -- candran.can:181 +macros["variables"][iast[1]] = replacement -- candran.can:182 +else -- candran.can:182 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:184 +end -- candran.can:184 +end -- candran.can:184 +if options["builtInMacros"] then -- candran.can:189 +env["define"]("__STR__(x)", function(x) -- candran.can:190 +return ("%q"):format(x) -- candran.can:190 +end) -- candran.can:190 +local s = require("candran.serpent") -- candran.can:191 +env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:192 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:193 +end) -- candran.can:193 end -- candran.can:193 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:196 -if not preprocess then -- candran.can:197 -return nil, "in preprocessor: " .. err -- candran.can:198 -end -- candran.can:198 -local success, output = pcall(preprocess) -- candran.can:202 -if not success then -- candran.can:203 -return nil, "in preprocessor: " .. output -- candran.can:204 -end -- candran.can:204 -return output, macros -- candran.can:207 -end -- candran.can:207 -candran["compile"] = function(input, options, macros) -- candran.can:217 -if options == nil then options = {} end -- candran.can:217 -options = util["merge"](candran["default"], options) -- candran.can:218 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:220 -if not ast then -- candran.can:222 -return nil, errmsg -- candran.can:223 -end -- candran.can:223 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:226 -end -- candran.can:226 -candran["make"] = function(code, options) -- candran.can:235 -local r, err = candran["preprocess"](code, options) -- candran.can:236 -if r then -- candran.can:237 -r, err = candran["compile"](r, options, err) -- candran.can:238 -if r then -- candran.can:239 -return r -- candran.can:240 -end -- candran.can:240 -end -- candran.can:240 -return r, err -- candran.can:243 -end -- candran.can:243 -local errorRewritingActive = false -- candran.can:246 -local codeCache = {} -- candran.can:247 -candran["loadfile"] = function(filepath, env, options) -- candran.can:250 -local f, err = io["open"](filepath) -- candran.can:251 -if not f then -- candran.can:252 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:253 -end -- candran.can:253 -local content = f:read("*a") -- candran.can:255 -f:close() -- candran.can:256 -return candran["load"](content, filepath, env, options) -- candran.can:258 -end -- candran.can:258 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:263 -if options == nil then options = {} end -- candran.can:263 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:264 -local code, err = candran["make"](chunk, options) -- candran.can:266 -if not code then -- candran.can:267 -return code, err -- candran.can:268 -end -- candran.can:268 -codeCache[options["chunkname"]] = code -- candran.can:271 -local f -- candran.can:272 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:273 -if f == nil then -- candran.can:278 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:279 -end -- candran.can:279 -if options["rewriteErrors"] == false then -- candran.can:282 -return f -- candran.can:283 -else -- candran.can:283 -return function(...) -- candran.can:285 -if not errorRewritingActive then -- candran.can:286 -errorRewritingActive = true -- candran.can:287 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:288 -errorRewritingActive = false -- candran.can:289 -if t[1] == false then -- candran.can:290 -error(t[2], 0) -- candran.can:291 -end -- candran.can:291 -return unpack(t, 2) -- candran.can:293 -else -- candran.can:293 -return f(...) -- candran.can:295 -end -- candran.can:295 -end -- candran.can:295 -end -- candran.can:295 -end -- candran.can:295 -candran["dofile"] = function(filename, options) -- candran.can:303 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:304 -if f == nil then -- candran.can:306 -error(err) -- candran.can:307 -else -- candran.can:307 -return f() -- candran.can:309 -end -- candran.can:309 -end -- candran.can:309 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:315 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:198 +if not preprocess then -- candran.can:199 +return nil, "in preprocessor: " .. err -- candran.can:200 +end -- candran.can:200 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:203 +if not preprocess then -- candran.can:204 +return nil, "in preprocessor: " .. err -- candran.can:205 +end -- candran.can:205 +local success, output = pcall(preprocess) -- candran.can:209 +if not success then -- candran.can:210 +return nil, "in preprocessor: " .. output -- candran.can:211 +end -- candran.can:211 +return output, macros -- candran.can:214 +end -- candran.can:214 +candran["compile"] = function(input, options, macros) -- candran.can:224 +if options == nil then options = {} end -- candran.can:224 +options = util["merge"](candran["default"], options) -- candran.can:225 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:227 +if not ast then -- candran.can:229 +return nil, errmsg -- candran.can:230 +end -- candran.can:230 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:233 +end -- candran.can:233 +candran["make"] = function(code, options) -- candran.can:242 +local r, err = candran["preprocess"](code, options) -- candran.can:243 +if r then -- candran.can:244 +r, err = candran["compile"](r, options, err) -- candran.can:245 +if r then -- candran.can:246 +return r -- candran.can:247 +end -- candran.can:247 +end -- candran.can:247 +return r, err -- candran.can:250 +end -- candran.can:250 +local errorRewritingActive = false -- candran.can:253 +local codeCache = {} -- candran.can:254 +candran["loadfile"] = function(filepath, env, options) -- candran.can:257 +local f, err = io["open"](filepath) -- candran.can:258 +if not f then -- candran.can:259 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:260 +end -- candran.can:260 +local content = f:read("*a") -- candran.can:262 +f:close() -- candran.can:263 +return candran["load"](content, filepath, env, options) -- candran.can:265 +end -- candran.can:265 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:270 +if options == nil then options = {} end -- candran.can:270 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:271 +local code, err = candran["make"](chunk, options) -- candran.can:273 +if not code then -- candran.can:274 +return code, err -- candran.can:275 +end -- candran.can:275 +codeCache[options["chunkname"]] = code -- candran.can:278 +local f -- candran.can:279 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:280 +if f == nil then -- candran.can:285 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:286 +end -- candran.can:286 +if options["rewriteErrors"] == false then -- candran.can:289 +return f -- candran.can:290 +else -- candran.can:290 +return function(...) -- candran.can:292 +if not errorRewritingActive then -- candran.can:293 +errorRewritingActive = true -- candran.can:294 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:295 +errorRewritingActive = false -- candran.can:296 +if t[1] == false then -- candran.can:297 +error(t[2], 0) -- candran.can:298 +end -- candran.can:298 +return unpack(t, 2) -- candran.can:300 +else -- candran.can:300 +return f(...) -- candran.can:302 +end -- candran.can:302 +end -- candran.can:302 +end -- candran.can:302 +end -- candran.can:302 +candran["dofile"] = function(filename, options) -- candran.can:310 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:311 +if f == nil then -- candran.can:313 +error(err) -- candran.can:314 +else -- candran.can:314 +return f() -- candran.can:316 +end -- candran.can:316 +end -- candran.can:316 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:322 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:316 -message = debug["traceback"](message, 2) -- candran.can:317 -end -- candran.can:317 +") then -- candran.can:323 +message = debug["traceback"](message, 2) -- candran.can:324 +end -- candran.can:324 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:319 -line = tonumber(line) -- candran.can:320 -local originalFile -- candran.can:322 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:323 -if strName then -- candran.can:324 -if codeCache[strName] then -- candran.can:325 -originalFile = codeCache[strName] -- candran.can:326 -source = strName -- candran.can:327 -end -- candran.can:327 -else -- candran.can:327 -do -- candran.can:330 -local fi -- candran.can:330 -fi = io["open"](source, "r") -- candran.can:330 -if fi then -- candran.can:330 -originalFile = fi:read("*a") -- candran.can:331 -fi:close() -- candran.can:332 -end -- candran.can:332 -end -- candran.can:332 -end -- candran.can:332 -if originalFile then -- candran.can:336 -local i = 0 -- candran.can:337 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:326 +line = tonumber(line) -- candran.can:327 +local originalFile -- candran.can:329 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:330 +if strName then -- candran.can:331 +if codeCache[strName] then -- candran.can:332 +originalFile = codeCache[strName] -- candran.can:333 +source = strName -- candran.can:334 +end -- candran.can:334 +else -- candran.can:334 +do -- candran.can:337 +local fi -- candran.can:337 +fi = io["open"](source, "r") -- candran.can:337 +if fi then -- candran.can:337 +originalFile = fi:read("*a") -- candran.can:338 +fi:close() -- candran.can:339 +end -- candran.can:339 +end -- candran.can:339 +end -- candran.can:339 +if originalFile then -- candran.can:343 +local i = 0 -- candran.can:344 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:338 -i = i + 1 -- candran.can:339 -if i == line then -- candran.can:340 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:341 -if lineMap then -- candran.can:342 -if extSource ~= source then -- candran.can:343 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:344 -else -- candran.can:344 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:346 -end -- candran.can:346 -end -- candran.can:346 -break -- candran.can:349 -end -- candran.can:349 -end -- candran.can:349 -end -- candran.can:349 -end) -- candran.can:349 -end -- candran.can:349 -candran["searcher"] = function(modpath) -- candran.can:357 -local filepath = util["search"](modpath, { "can" }) -- candran.can:358 -if not filepath then -- candran.can:359 -if _VERSION == "Lua 5.4" then -- candran.can:360 -return "no candran file in package.path" -- candran.can:361 -else -- candran.can:361 +") do -- candran.can:345 +i = i + 1 -- candran.can:346 +if i == line then -- candran.can:347 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:348 +if lineMap then -- candran.can:349 +if extSource ~= source then -- candran.can:350 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:351 +else -- candran.can:351 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:353 +end -- candran.can:353 +end -- candran.can:353 +break -- candran.can:356 +end -- candran.can:356 +end -- candran.can:356 +end -- candran.can:356 +end) -- candran.can:356 +end -- candran.can:356 +candran["searcher"] = function(modpath) -- candran.can:364 +local filepath = util["search"](modpath, { "can" }) -- candran.can:365 +if not filepath then -- candran.can:366 +if _VERSION == "Lua 5.4" then -- candran.can:367 +return "no candran file in package.path" -- candran.can:368 +else -- candran.can:368 return "\ -\9no candran file in package.path" -- candran.can:363 -end -- candran.can:363 -end -- candran.can:363 -return function(modpath) -- candran.can:366 -local r, s = candran["loadfile"](filepath) -- candran.can:367 -if r then -- candran.can:368 -return r(modpath, filepath) -- candran.can:369 -else -- candran.can:369 +\9no candran file in package.path" -- candran.can:370 +end -- candran.can:370 +end -- candran.can:370 +return function(modpath) -- candran.can:373 +local r, s = candran["loadfile"](filepath) -- candran.can:374 +if r then -- candran.can:375 +return r(modpath, filepath) -- candran.can:376 +else -- candran.can:376 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:371 -end -- candran.can:371 -end, filepath -- candran.can:373 -end -- candran.can:373 -candran["setup"] = function() -- candran.can:377 -local searchers = (function() -- candran.can:378 -if _VERSION == "Lua 5.1" then -- candran.can:378 -return package["loaders"] -- candran.can:379 -else -- candran.can:379 -return package["searchers"] -- candran.can:381 -end -- candran.can:381 -end)() -- candran.can:381 -for _, s in ipairs(searchers) do -- candran.can:384 -if s == candran["searcher"] then -- candran.can:385 -return candran -- candran.can:386 -end -- candran.can:386 -end -- candran.can:386 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:390 -return candran -- candran.can:391 -end -- candran.can:391 -return candran -- candran.can:394 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:378 +end -- candran.can:378 +end, filepath -- candran.can:380 +end -- candran.can:380 +candran["setup"] = function() -- candran.can:384 +local searchers = (function() -- candran.can:385 +if _VERSION == "Lua 5.1" then -- candran.can:385 +return package["loaders"] -- candran.can:386 +else -- candran.can:386 +return package["searchers"] -- candran.can:388 +end -- candran.can:388 +end)() -- candran.can:388 +for _, s in ipairs(searchers) do -- candran.can:391 +if s == candran["searcher"] then -- candran.can:392 +return candran -- candran.can:393 +end -- candran.can:393 +end -- candran.can:393 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:397 +return candran -- candran.can:398 +end -- candran.can:398 +return candran -- candran.can:401 diff --git a/candran/util.can b/candran/util.can index faf4a69..f666935 100644 --- a/candran/util.can +++ b/candran/util.can @@ -84,6 +84,11 @@ util.cli = { :description "Define a preprocessor constant" :args("1-2") :argname{"name", "value"} + :count("*"), + + parser:option("-I --import") + :description "Statically import a module into the compiled file" + :argname("module") :count("*") ) @@ -110,7 +115,8 @@ util.cli = { chunkname = args.chunkname, rewriteErrors = not args.no_rewrite_errors, builtInMacros = not args.no_builtin_macros, - preprocessorEnv = preprocessorEnv + preprocessorEnv = preprocessorEnv, + import = args.import } return options end From d4102f1af67954a7d0aebb68f487d54d929cd88f Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 14:23:45 +0200 Subject: [PATCH 44/52] Handle static import errors in can --- bin/can | 24 +++++++-- candran.can | 1 + candran.lua | 153 ++++++++++++++++++++++++++-------------------------- 3 files changed, 97 insertions(+), 81 deletions(-) diff --git a/bin/can b/bin/can index 903dea2..8a0fc97 100644 --- a/bin/can +++ b/bin/can @@ -118,6 +118,20 @@ else print("Candran " .. candran.VERSION .. ", targeting " .. candran.default.target) candran.setup() + -- only perform static imports once, on startup + do + local r, e = candran.load("local _", "stdin") + if not r then + print("In static import: "..e) + else + r, e = pcall(r) + if not r then + print("In static import: "..e) + end + end + candran.default.import = {} + end + -- REPL loop local multiline = false -- true if wait for another line local buffer @@ -157,15 +171,15 @@ else end -- exec - local t = { pcall(candran.load, buffer, "stdin") } - if t[1] == false then - if t[2]:match("expected '[end})]+' to close") then + local r, e = candran.load(buffer, "stdin") + if not r then + if e:match("expected '[end})]+' to close") then multiline = true else - print(t[2]) + print(e) end else - t = { pcall(t[2]) } + local t = { pcall(r) } if t[1] == false then print(t[2]) elseif #t > 1 then diff --git a/candran.can b/candran.can index 4e90067..3ebd2e5 100644 --- a/candran.can +++ b/candran.can @@ -320,6 +320,7 @@ end --- Candran error message handler. -- Use it in xpcall to rewrite stacktraces to display Candran source file lines instead of compiled Lua lines. function candran.messageHandler(message, noTraceback) + message = tostring(message) if not noTraceback and not message:match("\nstack traceback:\n") then message = debug.traceback(message, 2) end diff --git a/candran.lua b/candran.lua index 8ea8eb7..0afc80b 100644 --- a/candran.lua +++ b/candran.lua @@ -7251,88 +7251,89 @@ return f() -- candran.can:316 end -- candran.can:316 end -- candran.can:316 candran["messageHandler"] = function(message, noTraceback) -- candran.can:322 +message = tostring(message) -- candran.can:323 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:323 -message = debug["traceback"](message, 2) -- candran.can:324 -end -- candran.can:324 +") then -- candran.can:324 +message = debug["traceback"](message, 2) -- candran.can:325 +end -- candran.can:325 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:326 -line = tonumber(line) -- candran.can:327 -local originalFile -- candran.can:329 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:330 -if strName then -- candran.can:331 -if codeCache[strName] then -- candran.can:332 -originalFile = codeCache[strName] -- candran.can:333 -source = strName -- candran.can:334 -end -- candran.can:334 -else -- candran.can:334 -do -- candran.can:337 -local fi -- candran.can:337 -fi = io["open"](source, "r") -- candran.can:337 -if fi then -- candran.can:337 -originalFile = fi:read("*a") -- candran.can:338 -fi:close() -- candran.can:339 -end -- candran.can:339 -end -- candran.can:339 -end -- candran.can:339 -if originalFile then -- candran.can:343 -local i = 0 -- candran.can:344 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:327 +line = tonumber(line) -- candran.can:328 +local originalFile -- candran.can:330 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:331 +if strName then -- candran.can:332 +if codeCache[strName] then -- candran.can:333 +originalFile = codeCache[strName] -- candran.can:334 +source = strName -- candran.can:335 +end -- candran.can:335 +else -- candran.can:335 +do -- candran.can:338 +local fi -- candran.can:338 +fi = io["open"](source, "r") -- candran.can:338 +if fi then -- candran.can:338 +originalFile = fi:read("*a") -- candran.can:339 +fi:close() -- candran.can:340 +end -- candran.can:340 +end -- candran.can:340 +end -- candran.can:340 +if originalFile then -- candran.can:344 +local i = 0 -- candran.can:345 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:345 -i = i + 1 -- candran.can:346 -if i == line then -- candran.can:347 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:348 -if lineMap then -- candran.can:349 -if extSource ~= source then -- candran.can:350 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:351 -else -- candran.can:351 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:353 -end -- candran.can:353 -end -- candran.can:353 -break -- candran.can:356 -end -- candran.can:356 -end -- candran.can:356 -end -- candran.can:356 -end) -- candran.can:356 -end -- candran.can:356 -candran["searcher"] = function(modpath) -- candran.can:364 -local filepath = util["search"](modpath, { "can" }) -- candran.can:365 -if not filepath then -- candran.can:366 -if _VERSION == "Lua 5.4" then -- candran.can:367 -return "no candran file in package.path" -- candran.can:368 -else -- candran.can:368 +") do -- candran.can:346 +i = i + 1 -- candran.can:347 +if i == line then -- candran.can:348 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:349 +if lineMap then -- candran.can:350 +if extSource ~= source then -- candran.can:351 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:352 +else -- candran.can:352 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:354 +end -- candran.can:354 +end -- candran.can:354 +break -- candran.can:357 +end -- candran.can:357 +end -- candran.can:357 +end -- candran.can:357 +end) -- candran.can:357 +end -- candran.can:357 +candran["searcher"] = function(modpath) -- candran.can:365 +local filepath = util["search"](modpath, { "can" }) -- candran.can:366 +if not filepath then -- candran.can:367 +if _VERSION == "Lua 5.4" then -- candran.can:368 +return "no candran file in package.path" -- candran.can:369 +else -- candran.can:369 return "\ -\9no candran file in package.path" -- candran.can:370 -end -- candran.can:370 -end -- candran.can:370 -return function(modpath) -- candran.can:373 -local r, s = candran["loadfile"](filepath) -- candran.can:374 -if r then -- candran.can:375 -return r(modpath, filepath) -- candran.can:376 -else -- candran.can:376 +\9no candran file in package.path" -- candran.can:371 +end -- candran.can:371 +end -- candran.can:371 +return function(modpath) -- candran.can:374 +local r, s = candran["loadfile"](filepath) -- candran.can:375 +if r then -- candran.can:376 +return r(modpath, filepath) -- candran.can:377 +else -- candran.can:377 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:378 -end -- candran.can:378 -end, filepath -- candran.can:380 -end -- candran.can:380 -candran["setup"] = function() -- candran.can:384 -local searchers = (function() -- candran.can:385 -if _VERSION == "Lua 5.1" then -- candran.can:385 -return package["loaders"] -- candran.can:386 -else -- candran.can:386 -return package["searchers"] -- candran.can:388 -end -- candran.can:388 -end)() -- candran.can:388 -for _, s in ipairs(searchers) do -- candran.can:391 -if s == candran["searcher"] then -- candran.can:392 -return candran -- candran.can:393 -end -- candran.can:393 -end -- candran.can:393 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:397 -return candran -- candran.can:398 -end -- candran.can:398 -return candran -- candran.can:401 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:379 +end -- candran.can:379 +end, filepath -- candran.can:381 +end -- candran.can:381 +candran["setup"] = function() -- candran.can:385 +local searchers = (function() -- candran.can:386 +if _VERSION == "Lua 5.1" then -- candran.can:386 +return package["loaders"] -- candran.can:387 +else -- candran.can:387 +return package["searchers"] -- candran.can:389 +end -- candran.can:389 +end)() -- candran.can:389 +for _, s in ipairs(searchers) do -- candran.can:392 +if s == candran["searcher"] then -- candran.can:393 +return candran -- candran.can:394 +end -- candran.can:394 +end -- candran.can:394 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:398 +return candran -- candran.can:399 +end -- candran.can:399 +return candran -- candran.can:402 From 53f715cc6fdf5e10afa927f7ef794dd64154ac98 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 14:37:45 +0200 Subject: [PATCH 45/52] Add #set to define preprocessors constants from an imported file --- candran.can | 4 + candran.lua | 530 +++++++++++++++++----------------------------------- 2 files changed, 177 insertions(+), 357 deletions(-) diff --git a/candran.can b/candran.can index 3ebd2e5..9dd417c 100644 --- a/candran.can +++ b/candran.can @@ -184,6 +184,10 @@ function candran.preprocess(input, options={}) error("invalid macro type %s":format(tostring(iast.tag))) end end + env.set = function(identifier, value) + options.preprocessorEnv[identifier] = value + env[identifier] = value + end -- default macros if options.builtInMacros then diff --git a/candran.lua b/candran.lua index 0afc80b..d09d73f 100644 --- a/candran.lua +++ b/candran.lua @@ -2220,14 +2220,6 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 -targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 -if t[2] then -- ./compiler/lua53.can:5 -error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 -else -- ./compiler/lua53.can:6 -return t[1] -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -3167,39 +3159,6 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 -targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 -if t[2] then -- ./compiler/lua53.can:5 -error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 -else -- ./compiler/lua53.can:6 -return t[1] -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -targetName = "Lua 5.2" -- ./compiler/lua52.can:1 -APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 -return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 -end -- ./compiler/lua52.can:4 -tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 -return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 -end -- ./compiler/lua52.can:8 -tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 -return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 -end -- ./compiler/lua52.can:11 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 -return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 -end -- ./compiler/lua52.can:14 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 -return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 -end -- ./compiler/lua52.can:17 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 -return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 -end -- ./compiler/lua52.can:20 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 -return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 -end -- ./compiler/lua52.can:23 -tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 -return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 -end -- ./compiler/lua52.can:26 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -4143,67 +4102,6 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 -targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 -if t[2] then -- ./compiler/lua53.can:5 -error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 -else -- ./compiler/lua53.can:6 -return t[1] -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -targetName = "Lua 5.2" -- ./compiler/lua52.can:1 -APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 -return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 -end -- ./compiler/lua52.can:4 -tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 -return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 -end -- ./compiler/lua52.can:8 -tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 -return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 -end -- ./compiler/lua52.can:11 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 -return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 -end -- ./compiler/lua52.can:14 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 -return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 -end -- ./compiler/lua52.can:17 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 -return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 -end -- ./compiler/lua52.can:20 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 -return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 -end -- ./compiler/lua52.can:23 -tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 -return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 -end -- ./compiler/lua52.can:26 -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 -tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 -addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 -return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 -end -- ./compiler/luajit.can:9 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 -addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 -return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 -end -- ./compiler/luajit.can:13 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 -addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 -return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 -end -- ./compiler/luajit.can:17 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 -addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 -return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 -end -- ./compiler/luajit.can:21 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 -addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 -return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 -end -- ./compiler/luajit.can:25 -tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 -addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 -return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 -end -- ./compiler/luajit.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -5151,92 +5049,6 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 -targetName = "Lua 5.3" -- ./compiler/lua53.can:1 -tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 -if t[2] then -- ./compiler/lua53.can:5 -error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 -else -- ./compiler/lua53.can:6 -return t[1] -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -end -- ./compiler/lua53.can:8 -targetName = "Lua 5.2" -- ./compiler/lua52.can:1 -APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 -return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 -end -- ./compiler/lua52.can:4 -tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 -return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 -end -- ./compiler/lua52.can:8 -tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 -return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 -end -- ./compiler/lua52.can:11 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 -return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 -end -- ./compiler/lua52.can:14 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 -return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 -end -- ./compiler/lua52.can:17 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 -return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 -end -- ./compiler/lua52.can:20 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 -return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 -end -- ./compiler/lua52.can:23 -tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 -return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 -end -- ./compiler/lua52.can:26 -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 -tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 -addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 -return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 -end -- ./compiler/luajit.can:9 -tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 -addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 -return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 -end -- ./compiler/luajit.can:13 -tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 -addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 -return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 -end -- ./compiler/luajit.can:17 -tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 -addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 -return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 -end -- ./compiler/luajit.can:21 -tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 -addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 -return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 -end -- ./compiler/luajit.can:25 -tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 -addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 -return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 -end -- ./compiler/luajit.can:29 -targetName = "Lua 5.1" -- ./compiler/lua51.can:1 -states["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"] = function() -- ./compiler/lua51.can:25 -error("target " .. targetName .. " does not support gotos") -- ./compiler/lua51.can:26 -end -- ./compiler/lua51.can:26 -tags["Label"] = function() -- ./compiler/lua51.can:28 -error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 -end -- ./compiler/lua51.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -7158,182 +6970,186 @@ else -- candran.can:182 error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:184 end -- candran.can:184 end -- candran.can:184 -if options["builtInMacros"] then -- candran.can:189 -env["define"]("__STR__(x)", function(x) -- candran.can:190 -return ("%q"):format(x) -- candran.can:190 -end) -- candran.can:190 -local s = require("candran.serpent") -- candran.can:191 -env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:192 -return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:193 -end) -- candran.can:193 -end -- candran.can:193 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:198 -if not preprocess then -- candran.can:199 -return nil, "in preprocessor: " .. err -- candran.can:200 -end -- candran.can:200 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:203 -if not preprocess then -- candran.can:204 -return nil, "in preprocessor: " .. err -- candran.can:205 -end -- candran.can:205 -local success, output = pcall(preprocess) -- candran.can:209 -if not success then -- candran.can:210 -return nil, "in preprocessor: " .. output -- candran.can:211 -end -- candran.can:211 -return output, macros -- candran.can:214 -end -- candran.can:214 -candran["compile"] = function(input, options, macros) -- candran.can:224 -if options == nil then options = {} end -- candran.can:224 -options = util["merge"](candran["default"], options) -- candran.can:225 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:227 -if not ast then -- candran.can:229 -return nil, errmsg -- candran.can:230 -end -- candran.can:230 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:233 -end -- candran.can:233 -candran["make"] = function(code, options) -- candran.can:242 -local r, err = candran["preprocess"](code, options) -- candran.can:243 -if r then -- candran.can:244 -r, err = candran["compile"](r, options, err) -- candran.can:245 -if r then -- candran.can:246 -return r -- candran.can:247 -end -- candran.can:247 -end -- candran.can:247 -return r, err -- candran.can:250 -end -- candran.can:250 -local errorRewritingActive = false -- candran.can:253 -local codeCache = {} -- candran.can:254 -candran["loadfile"] = function(filepath, env, options) -- candran.can:257 -local f, err = io["open"](filepath) -- candran.can:258 -if not f then -- candran.can:259 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:260 -end -- candran.can:260 -local content = f:read("*a") -- candran.can:262 -f:close() -- candran.can:263 -return candran["load"](content, filepath, env, options) -- candran.can:265 -end -- candran.can:265 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:270 -if options == nil then options = {} end -- candran.can:270 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:271 -local code, err = candran["make"](chunk, options) -- candran.can:273 -if not code then -- candran.can:274 -return code, err -- candran.can:275 -end -- candran.can:275 -codeCache[options["chunkname"]] = code -- candran.can:278 -local f -- candran.can:279 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:280 -if f == nil then -- candran.can:285 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:286 -end -- candran.can:286 -if options["rewriteErrors"] == false then -- candran.can:289 -return f -- candran.can:290 -else -- candran.can:290 -return function(...) -- candran.can:292 -if not errorRewritingActive then -- candran.can:293 -errorRewritingActive = true -- candran.can:294 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:295 -errorRewritingActive = false -- candran.can:296 -if t[1] == false then -- candran.can:297 -error(t[2], 0) -- candran.can:298 -end -- candran.can:298 -return unpack(t, 2) -- candran.can:300 -else -- candran.can:300 -return f(...) -- candran.can:302 +env["set"] = function(identifier, value) -- candran.can:187 +options["preprocessorEnv"][identifier] = value -- candran.can:188 +env[identifier] = value -- candran.can:189 +end -- candran.can:189 +if options["builtInMacros"] then -- candran.can:193 +env["define"]("__STR__(x)", function(x) -- candran.can:194 +return ("%q"):format(x) -- candran.can:194 +end) -- candran.can:194 +local s = require("candran.serpent") -- candran.can:195 +env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:196 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:197 +end) -- candran.can:197 +end -- candran.can:197 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:202 +if not preprocess then -- candran.can:203 +return nil, "in preprocessor: " .. err -- candran.can:204 +end -- candran.can:204 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:207 +if not preprocess then -- candran.can:208 +return nil, "in preprocessor: " .. err -- candran.can:209 +end -- candran.can:209 +local success, output = pcall(preprocess) -- candran.can:213 +if not success then -- candran.can:214 +return nil, "in preprocessor: " .. output -- candran.can:215 +end -- candran.can:215 +return output, macros -- candran.can:218 +end -- candran.can:218 +candran["compile"] = function(input, options, macros) -- candran.can:228 +if options == nil then options = {} end -- candran.can:228 +options = util["merge"](candran["default"], options) -- candran.can:229 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:231 +if not ast then -- candran.can:233 +return nil, errmsg -- candran.can:234 +end -- candran.can:234 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:237 +end -- candran.can:237 +candran["make"] = function(code, options) -- candran.can:246 +local r, err = candran["preprocess"](code, options) -- candran.can:247 +if r then -- candran.can:248 +r, err = candran["compile"](r, options, err) -- candran.can:249 +if r then -- candran.can:250 +return r -- candran.can:251 +end -- candran.can:251 +end -- candran.can:251 +return r, err -- candran.can:254 +end -- candran.can:254 +local errorRewritingActive = false -- candran.can:257 +local codeCache = {} -- candran.can:258 +candran["loadfile"] = function(filepath, env, options) -- candran.can:261 +local f, err = io["open"](filepath) -- candran.can:262 +if not f then -- candran.can:263 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:264 +end -- candran.can:264 +local content = f:read("*a") -- candran.can:266 +f:close() -- candran.can:267 +return candran["load"](content, filepath, env, options) -- candran.can:269 +end -- candran.can:269 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:274 +if options == nil then options = {} end -- candran.can:274 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:275 +local code, err = candran["make"](chunk, options) -- candran.can:277 +if not code then -- candran.can:278 +return code, err -- candran.can:279 +end -- candran.can:279 +codeCache[options["chunkname"]] = code -- candran.can:282 +local f -- candran.can:283 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:284 +if f == nil then -- candran.can:289 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:290 +end -- candran.can:290 +if options["rewriteErrors"] == false then -- candran.can:293 +return f -- candran.can:294 +else -- candran.can:294 +return function(...) -- candran.can:296 +if not errorRewritingActive then -- candran.can:297 +errorRewritingActive = true -- candran.can:298 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:299 +errorRewritingActive = false -- candran.can:300 +if t[1] == false then -- candran.can:301 +error(t[2], 0) -- candran.can:302 end -- candran.can:302 -end -- candran.can:302 -end -- candran.can:302 -end -- candran.can:302 -candran["dofile"] = function(filename, options) -- candran.can:310 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:311 -if f == nil then -- candran.can:313 -error(err) -- candran.can:314 -else -- candran.can:314 -return f() -- candran.can:316 -end -- candran.can:316 -end -- candran.can:316 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:322 -message = tostring(message) -- candran.can:323 +return unpack(t, 2) -- candran.can:304 +else -- candran.can:304 +return f(...) -- candran.can:306 +end -- candran.can:306 +end -- candran.can:306 +end -- candran.can:306 +end -- candran.can:306 +candran["dofile"] = function(filename, options) -- candran.can:314 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:315 +if f == nil then -- candran.can:317 +error(err) -- candran.can:318 +else -- candran.can:318 +return f() -- candran.can:320 +end -- candran.can:320 +end -- candran.can:320 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:326 +message = tostring(message) -- candran.can:327 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:324 -message = debug["traceback"](message, 2) -- candran.can:325 -end -- candran.can:325 +") then -- candran.can:328 +message = debug["traceback"](message, 2) -- candran.can:329 +end -- candran.can:329 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:327 -line = tonumber(line) -- candran.can:328 -local originalFile -- candran.can:330 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:331 -if strName then -- candran.can:332 -if codeCache[strName] then -- candran.can:333 -originalFile = codeCache[strName] -- candran.can:334 -source = strName -- candran.can:335 -end -- candran.can:335 -else -- candran.can:335 -do -- candran.can:338 -local fi -- candran.can:338 -fi = io["open"](source, "r") -- candran.can:338 -if fi then -- candran.can:338 -originalFile = fi:read("*a") -- candran.can:339 -fi:close() -- candran.can:340 -end -- candran.can:340 -end -- candran.can:340 -end -- candran.can:340 -if originalFile then -- candran.can:344 -local i = 0 -- candran.can:345 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:331 +line = tonumber(line) -- candran.can:332 +local originalFile -- candran.can:334 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:335 +if strName then -- candran.can:336 +if codeCache[strName] then -- candran.can:337 +originalFile = codeCache[strName] -- candran.can:338 +source = strName -- candran.can:339 +end -- candran.can:339 +else -- candran.can:339 +do -- candran.can:342 +local fi -- candran.can:342 +fi = io["open"](source, "r") -- candran.can:342 +if fi then -- candran.can:342 +originalFile = fi:read("*a") -- candran.can:343 +fi:close() -- candran.can:344 +end -- candran.can:344 +end -- candran.can:344 +end -- candran.can:344 +if originalFile then -- candran.can:348 +local i = 0 -- candran.can:349 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:346 -i = i + 1 -- candran.can:347 -if i == line then -- candran.can:348 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:349 -if lineMap then -- candran.can:350 -if extSource ~= source then -- candran.can:351 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:352 -else -- candran.can:352 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:354 -end -- candran.can:354 -end -- candran.can:354 -break -- candran.can:357 -end -- candran.can:357 -end -- candran.can:357 -end -- candran.can:357 -end) -- candran.can:357 -end -- candran.can:357 -candran["searcher"] = function(modpath) -- candran.can:365 -local filepath = util["search"](modpath, { "can" }) -- candran.can:366 -if not filepath then -- candran.can:367 -if _VERSION == "Lua 5.4" then -- candran.can:368 -return "no candran file in package.path" -- candran.can:369 -else -- candran.can:369 +") do -- candran.can:350 +i = i + 1 -- candran.can:351 +if i == line then -- candran.can:352 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:353 +if lineMap then -- candran.can:354 +if extSource ~= source then -- candran.can:355 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:356 +else -- candran.can:356 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:358 +end -- candran.can:358 +end -- candran.can:358 +break -- candran.can:361 +end -- candran.can:361 +end -- candran.can:361 +end -- candran.can:361 +end) -- candran.can:361 +end -- candran.can:361 +candran["searcher"] = function(modpath) -- candran.can:369 +local filepath = util["search"](modpath, { "can" }) -- candran.can:370 +if not filepath then -- candran.can:371 +if _VERSION == "Lua 5.4" then -- candran.can:372 +return "no candran file in package.path" -- candran.can:373 +else -- candran.can:373 return "\ -\9no candran file in package.path" -- candran.can:371 -end -- candran.can:371 -end -- candran.can:371 -return function(modpath) -- candran.can:374 -local r, s = candran["loadfile"](filepath) -- candran.can:375 -if r then -- candran.can:376 -return r(modpath, filepath) -- candran.can:377 -else -- candran.can:377 +\9no candran file in package.path" -- candran.can:375 +end -- candran.can:375 +end -- candran.can:375 +return function(modpath) -- candran.can:378 +local r, s = candran["loadfile"](filepath) -- candran.can:379 +if r then -- candran.can:380 +return r(modpath, filepath) -- candran.can:381 +else -- candran.can:381 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:379 -end -- candran.can:379 -end, filepath -- candran.can:381 -end -- candran.can:381 -candran["setup"] = function() -- candran.can:385 -local searchers = (function() -- candran.can:386 -if _VERSION == "Lua 5.1" then -- candran.can:386 -return package["loaders"] -- candran.can:387 -else -- candran.can:387 -return package["searchers"] -- candran.can:389 -end -- candran.can:389 -end)() -- candran.can:389 -for _, s in ipairs(searchers) do -- candran.can:392 -if s == candran["searcher"] then -- candran.can:393 -return candran -- candran.can:394 -end -- candran.can:394 -end -- candran.can:394 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:398 -return candran -- candran.can:399 -end -- candran.can:399 -return candran -- candran.can:402 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:383 +end -- candran.can:383 +end, filepath -- candran.can:385 +end -- candran.can:385 +candran["setup"] = function() -- candran.can:389 +local searchers = (function() -- candran.can:390 +if _VERSION == "Lua 5.1" then -- candran.can:390 +return package["loaders"] -- candran.can:391 +else -- candran.can:391 +return package["searchers"] -- candran.can:393 +end -- candran.can:393 +end)() -- candran.can:393 +for _, s in ipairs(searchers) do -- candran.can:396 +if s == candran["searcher"] then -- candran.can:397 +return candran -- candran.can:398 +end -- candran.can:398 +end -- candran.can:398 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:402 +return candran -- candran.can:403 +end -- candran.can:403 +return candran -- candran.can:406 From b32d4d5600dac205e19fda66138e828f5cf0c76e Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 15:14:56 +0200 Subject: [PATCH 46/52] Update README --- README.md | 48 ++++++++++---- candran.lua | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 66992aa..78adb83 100644 --- a/README.md +++ b/README.md @@ -456,6 +456,7 @@ The preprocessor has access to the following variables: * ````write(...)````: write to the preprocessor output. For example, ````#write("hello()")```` will output ````hello()```` in the final file. * ```placeholder(name)```: if the variable _name_ is defined in the preprocessor environement, its content will be inserted here. * ```define(identifier, replacement)```: define a macro. See below. +* ```set(identifier, value)```: set a preprocessor constant. * each arguments passed to the preprocessor is directly available in the environment. * and every standard Lua library. @@ -526,23 +527,41 @@ The library can be used standalone through the ```canc``` (for compiling Candran Preprocess and compile each _filename_ Candran files, and creates the assiociated ```.lua``` files in the same directories. - _options_ is of type ````-somearg -anotherarg thing=somestring other=5````, which will generate a Lua table ```{ somearg = true, anotherarg = true, thing = "somestring", other = 5 }```. + _options_ is of type ````--no-map-lines -p --include module -d VAR 5````. - You can choose to use another directory where files should be written using the ```dest=destinationDirectory``` argument. + You can choose to use another directory where files should be written using the `--destination` or `-d` option: ```--destination destinationDirectory```. - You can choose the output filename using ```out=filename```. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. + You can choose the output filename using `--output` or `-o` option: `--output filename`. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. - ```canc``` can write to the standard output instead of creating files using the ```-print``` argument. + ```canc``` can write to the standard output instead of creating files using the ```--print``` or `-p` argument. - You can choose to run only the preprocessor or compile using the ```-preprocess``` and ```-compile``` flags. + You can choose to run only the preprocessor or compile using the ```--preprocess``` and ```--compile``` flags. - You can choose to only parse the file and check it for syntaxic errors using the ```-parse``` flag. Errors will be printed to stderr in a similar format to ```luac -p```. + You can choose to only parse the file and check it for syntaxic errors using the ```--parse``` flag. Errors will be printed to stderr in a similar format to ```luac -p```. - The ```-ast``` flag is also available for debugging, and will disable preprocessing, compiling and file writing, and instead directly dump the AST generated from the input file(s) to stdout. + The ```--ast``` flag is also available for debugging, and will disable preprocessing, compiling and file writing, and instead directly dump the AST generated from the input file(s) to stdout. Instead of providing filenames, you can use ```-``` to read from standard input. - Use the ```-h``` or ```-help``` option to display a short help text. + You can change the compiler target using `--target` or `-t`: `--target luajit`. + + You can change the identation and newline string using `--indentation` and `--newline`: `--identation luajit`. + + You can change Candran's built-in variable prefix using `--variable-prefix`: `--variable-prefix __CAN_`. + + You can disable line mapping (error rewriting will not work) using `--no-map-lines`. + + You can disable built-in macros using `--no-builtin-macros`. + + You can define preprocessor constants using `--define` or `-D`: `--define VAR 5`. `VAR` will be available and set to 5 in the preprocessor. If you specify no value, it defaults to true. + + You can statically import modules using `--import` or `-I`: `--import module`. The module will be imported in compiled files using `#import("module",{loadLocal=false})`. + + You can disable error rewriting using `--no-rewrite-errors`. + + You can change the chunkname using `--chunkname`: `--chunkname filename`. This will change the filenames are reported in errors. By default, try to use the current file name, or stdin when using `-`. + + Use the ```-h``` or ```--help``` option to display the help text. Example uses: @@ -550,15 +569,15 @@ The library can be used standalone through the ```canc``` (for compiling Candran preprocess and compile _foo.can_ and write the result in _foo.lua_. - * ````canc indentation=" " foo.can```` + * ````canc --indentation " " foo.can```` preprocess and compile _foo.can_ with 2-space indentation (readable code!) and write the result in _foo.lua_. - * ````canc foo.can -verbose -print | lua```` + * ````canc foo.can -d verbose --print | lua```` - preprocess _foo.can_ with _verbose_ set to _true_, compile it and execute it. + preprocess _foo.can_ with _verbose_ set to _true_ in the preprocessor, compile it and execute it. - * ````canc -parse foo.can```` + * ````canc --parse foo.can```` checks foo.can for syntaxic errors. @@ -578,7 +597,9 @@ The library can be used standalone through the ```canc``` (for compiling Candran Instead of providing a filename, you can use ```-``` to read from standard input. - Use the ```-h``` or ```-help``` option to display a short help text. + Use similar options as `canc`. + + Use the ```-h``` or ```-help``` option to display the help text. * ```cancheck``` @@ -672,6 +693,7 @@ chunkname = "nil" -- the chunkname used when running code using the helper funct rewriteErrors = true -- true to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall(). builtInMacros = true -- false to disable built-in macros __*__ preprocessorEnv = {} -- environment to merge with the preprocessor environement +import = {} -- list of modules to automatically import in compiled files (using #import("module",{loadLocal=false})) ``` You can change the defaults used for these variables in the table `candran.default`. diff --git a/candran.lua b/candran.lua index d09d73f..a7038d6 100644 --- a/candran.lua +++ b/candran.lua @@ -2220,6 +2220,14 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -3159,6 +3167,39 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -4102,6 +4143,67 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +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 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -5049,6 +5151,92 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +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 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 +targetName = "Lua 5.1" -- ./compiler/lua51.can:1 +states["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"] = function() -- ./compiler/lua51.can:25 +error("target " .. targetName .. " does not support gotos") -- ./compiler/lua51.can:26 +end -- ./compiler/lua51.can:26 +tags["Label"] = function() -- ./compiler/lua51.can:28 +error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 +end -- ./compiler/lua51.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 From 56f1901f9b86c25862c4e50e75e81028905e8fdf Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 15:26:33 +0200 Subject: [PATCH 47/52] Fix #set changing global state --- candran.can | 10 +- candran.lua | 486 ++++++++++++++++++++++++++-------------------------- 2 files changed, 251 insertions(+), 245 deletions(-) diff --git a/candran.can b/candran.can index 9dd417c..aee5c57 100644 --- a/candran.can +++ b/candran.can @@ -53,7 +53,7 @@ end -- @treturn[1] macros registered macros -- @treturn[2] nil nil if error -- @treturn[2] error string error message -function candran.preprocess(input, options={}) +function candran.preprocess(input, options={}, _env) options = util.merge(candran.default, options) local macros = { functions = {}, @@ -98,6 +98,7 @@ function candran.preprocess(input, options={}) preprocessor ..= "return output" -- make preprocessor environement + local exportenv = {} local env = util.merge(_G, options.preprocessorEnv) --- Candran library table env.candran = candran @@ -118,8 +119,9 @@ function candran.preprocess(input, options={}) margs = util.merge(options, { chunkname = filepath, loadLocal = true, loadPackage = true }, margs) margs.import = {} -- no need for recursive import - local modcontent, modmacros = assert(candran.preprocess(f:read("*a"), margs)) + local modcontent, modmacros, modenv = assert(candran.preprocess(f:read("*a"), margs)) macros = util.recmerge(macros, modmacros) + for k, v in pairs(modenv) do env[k] = v end f:close() -- get module name (ex: module name of path.to.module is module) @@ -185,7 +187,7 @@ function candran.preprocess(input, options={}) end end env.set = function(identifier, value) - options.preprocessorEnv[identifier] = value + exportenv[identifier] = value env[identifier] = value end @@ -215,7 +217,7 @@ function candran.preprocess(input, options={}) return nil, "in preprocessor: "..output end - return output, macros + return output, macros, exportenv end --- Run the compiler diff --git a/candran.lua b/candran.lua index a7038d6..4df71ec 100644 --- a/candran.lua +++ b/candran.lua @@ -7038,7 +7038,7 @@ candran["default"]["target"] = "lua52" -- candran.can:44 elseif _VERSION == "Lua 5.3" then -- candran.can:45 candran["default"]["target"] = "lua53" -- candran.can:46 end -- candran.can:46 -candran["preprocess"] = function(input, options) -- candran.can:56 +candran["preprocess"] = function(input, options, _env) -- candran.can:56 if options == nil then options = {} end -- candran.can:56 options = util["merge"](candran["default"], options) -- candran.can:57 local macros = { -- candran.can:58 @@ -7082,262 +7082,266 @@ end -- candran.can:94 end -- candran.can:94 end -- candran.can:94 preprocessor = preprocessor .. ("return output") -- candran.can:98 -local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:101 -env["candran"] = candran -- candran.can:103 -env["output"] = "" -- candran.can:105 -env["import"] = function(modpath, margs) -- candran.can:112 -if margs == nil then margs = {} end -- candran.can:112 -local filepath = assert(util["search"](modpath, { -- candran.can:113 -"can", -- candran.can:113 -"lua" -- candran.can:113 -}), "No module named \"" .. modpath .. "\"") -- candran.can:113 -local f = io["open"](filepath) -- candran.can:116 -if not f then -- candran.can:117 -error("can't open the module file to import") -- candran.can:117 -end -- candran.can:117 -margs = util["merge"](options, { -- candran.can:119 -["chunkname"] = filepath, -- candran.can:119 -["loadLocal"] = true, -- candran.can:119 -["loadPackage"] = true -- candran.can:119 -}, margs) -- candran.can:119 -margs["import"] = {} -- candran.can:120 -local modcontent, modmacros = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:121 -macros = util["recmerge"](macros, modmacros) -- candran.can:122 -f:close() -- candran.can:123 -local modname = modpath:match("[^%.]+$") -- candran.can:126 +local exportenv = {} -- candran.can:101 +local env = util["merge"](_G, options["preprocessorEnv"]) -- candran.can:102 +env["candran"] = candran -- candran.can:104 +env["output"] = "" -- candran.can:106 +env["import"] = function(modpath, margs) -- candran.can:113 +if margs == nil then margs = {} end -- candran.can:113 +local filepath = assert(util["search"](modpath, { -- candran.can:114 +"can", -- candran.can:114 +"lua" -- candran.can:114 +}), "No module named \"" .. modpath .. "\"") -- candran.can:114 +local f = io["open"](filepath) -- candran.can:117 +if not f then -- candran.can:118 +error("can't open the module file to import") -- candran.can:118 +end -- candran.can:118 +margs = util["merge"](options, { -- candran.can:120 +["chunkname"] = filepath, -- candran.can:120 +["loadLocal"] = true, -- candran.can:120 +["loadPackage"] = true -- candran.can:120 +}, margs) -- candran.can:120 +margs["import"] = {} -- candran.can:121 +local modcontent, modmacros, modenv = assert(candran["preprocess"](f:read("*a"), margs)) -- candran.can:122 +macros = util["recmerge"](macros, modmacros) -- candran.can:123 +for k, v in pairs(modenv) do -- candran.can:124 +env[k] = v -- candran.can:124 +end -- candran.can:124 +f:close() -- candran.can:125 +local modname = modpath:match("[^%.]+$") -- candran.can:128 env["write"]("-- MODULE " .. modpath .. " --\ " .. "local function _()\ " .. modcontent .. "\ " .. "end\ " .. (margs["loadLocal"] and ("local %s = _() or %s\ "):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\ -"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:135 -end -- candran.can:135 -env["include"] = function(file) -- candran.can:140 -local f = io["open"](file) -- candran.can:141 -if not f then -- candran.can:142 -error("can't open the file " .. file .. " to include") -- candran.can:142 -end -- candran.can:142 -env["write"](f:read("*a")) -- candran.can:143 -f:close() -- candran.can:144 +"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --") -- candran.can:137 +end -- candran.can:137 +env["include"] = function(file) -- candran.can:142 +local f = io["open"](file) -- candran.can:143 +if not f then -- candran.can:144 +error("can't open the file " .. file .. " to include") -- candran.can:144 end -- candran.can:144 -env["write"] = function(...) -- candran.can:148 +env["write"](f:read("*a")) -- candran.can:145 +f:close() -- candran.can:146 +end -- candran.can:146 +env["write"] = function(...) -- candran.can:150 env["output"] = env["output"] .. (table["concat"]({ ... }, "\9") .. "\ -") -- candran.can:149 -end -- candran.can:149 -env["placeholder"] = function(name) -- candran.can:153 -if env[name] then -- candran.can:154 -env["write"](env[name]) -- candran.can:155 -end -- candran.can:155 -end -- candran.can:155 -env["define"] = function(identifier, replacement) -- candran.can:158 -local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:160 -if not iast then -- candran.can:161 -return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:162 -end -- candran.can:162 -if type(replacement) == "string" then -- candran.can:165 -local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:166 -if not rast then -- candran.can:167 -return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:168 -end -- candran.can:168 -if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:171 -rast = rast[1][1] -- candran.can:172 -end -- candran.can:172 -replacement = rast -- candran.can:174 -elseif type(replacement) ~= "function" then -- candran.can:175 -error("bad argument #2 to 'define' (string or function expected)") -- candran.can:176 -end -- candran.can:176 -if iast["tag"] == "MacroFunction" then -- candran.can:179 -macros["functions"][iast[1][1]] = { -- candran.can:180 -["args"] = iast[2], -- candran.can:180 -["replacement"] = replacement -- candran.can:180 -} -- candran.can:180 -elseif iast["tag"] == "Id" then -- candran.can:181 -macros["variables"][iast[1]] = replacement -- candran.can:182 -else -- candran.can:182 -error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:184 -end -- candran.can:184 -end -- candran.can:184 -env["set"] = function(identifier, value) -- candran.can:187 -options["preprocessorEnv"][identifier] = value -- candran.can:188 -env[identifier] = value -- candran.can:189 -end -- candran.can:189 -if options["builtInMacros"] then -- candran.can:193 -env["define"]("__STR__(x)", function(x) -- candran.can:194 -return ("%q"):format(x) -- candran.can:194 -end) -- candran.can:194 -local s = require("candran.serpent") -- candran.can:195 -env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:196 -return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:197 -end) -- candran.can:197 -end -- candran.can:197 -local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:202 -if not preprocess then -- candran.can:203 -return nil, "in preprocessor: " .. err -- candran.can:204 -end -- candran.can:204 -preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:207 -if not preprocess then -- candran.can:208 -return nil, "in preprocessor: " .. err -- candran.can:209 -end -- candran.can:209 -local success, output = pcall(preprocess) -- candran.can:213 -if not success then -- candran.can:214 -return nil, "in preprocessor: " .. output -- candran.can:215 -end -- candran.can:215 -return output, macros -- candran.can:218 -end -- candran.can:218 -candran["compile"] = function(input, options, macros) -- candran.can:228 -if options == nil then options = {} end -- candran.can:228 -options = util["merge"](candran["default"], options) -- candran.can:229 -local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:231 -if not ast then -- candran.can:233 -return nil, errmsg -- candran.can:234 -end -- candran.can:234 -return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:237 -end -- candran.can:237 -candran["make"] = function(code, options) -- candran.can:246 -local r, err = candran["preprocess"](code, options) -- candran.can:247 -if r then -- candran.can:248 -r, err = candran["compile"](r, options, err) -- candran.can:249 +") -- candran.can:151 +end -- candran.can:151 +env["placeholder"] = function(name) -- candran.can:155 +if env[name] then -- candran.can:156 +env["write"](env[name]) -- candran.can:157 +end -- candran.can:157 +end -- candran.can:157 +env["define"] = function(identifier, replacement) -- candran.can:160 +local iast, ierr = parser["parsemacroidentifier"](identifier, options["chunkname"]) -- candran.can:162 +if not iast then -- candran.can:163 +return error(("in macro identifier: %s"):format(tostring(ierr))) -- candran.can:164 +end -- candran.can:164 +if type(replacement) == "string" then -- candran.can:167 +local rast, rerr = parser["parse"](replacement, options["chunkname"]) -- candran.can:168 +if not rast then -- candran.can:169 +return error(("in macro replacement: %s"):format(tostring(rerr))) -- candran.can:170 +end -- candran.can:170 +if # rast == 1 and rast[1]["tag"] == "Push" and rast[1]["implicit"] then -- candran.can:173 +rast = rast[1][1] -- candran.can:174 +end -- candran.can:174 +replacement = rast -- candran.can:176 +elseif type(replacement) ~= "function" then -- candran.can:177 +error("bad argument #2 to 'define' (string or function expected)") -- candran.can:178 +end -- candran.can:178 +if iast["tag"] == "MacroFunction" then -- candran.can:181 +macros["functions"][iast[1][1]] = { -- candran.can:182 +["args"] = iast[2], -- candran.can:182 +["replacement"] = replacement -- candran.can:182 +} -- candran.can:182 +elseif iast["tag"] == "Id" then -- candran.can:183 +macros["variables"][iast[1]] = replacement -- candran.can:184 +else -- candran.can:184 +error(("invalid macro type %s"):format(tostring(iast["tag"]))) -- candran.can:186 +end -- candran.can:186 +end -- candran.can:186 +env["set"] = function(identifier, value) -- candran.can:189 +exportenv[identifier] = value -- candran.can:190 +env[identifier] = value -- candran.can:191 +end -- candran.can:191 +if options["builtInMacros"] then -- candran.can:195 +env["define"]("__STR__(x)", function(x) -- candran.can:196 +return ("%q"):format(x) -- candran.can:196 +end) -- candran.can:196 +local s = require("candran.serpent") -- candran.can:197 +env["define"]("__CONSTEXPR__(expr)", function(expr) -- candran.can:198 +return s["block"](assert(candran["load"](expr))(), { ["fatal"] = true }) -- candran.can:199 +end) -- candran.can:199 +end -- candran.can:199 +local preprocess, err = candran["compile"](preprocessor, options) -- candran.can:204 +if not preprocess then -- candran.can:205 +return nil, "in preprocessor: " .. err -- candran.can:206 +end -- candran.can:206 +preprocess, err = util["load"](preprocessor, "candran preprocessor", env) -- candran.can:209 +if not preprocess then -- candran.can:210 +return nil, "in preprocessor: " .. err -- candran.can:211 +end -- candran.can:211 +local success, output = pcall(preprocess) -- candran.can:215 +if not success then -- candran.can:216 +return nil, "in preprocessor: " .. output -- candran.can:217 +end -- candran.can:217 +return output, macros, exportenv -- candran.can:220 +end -- candran.can:220 +candran["compile"] = function(input, options, macros) -- candran.can:230 +if options == nil then options = {} end -- candran.can:230 +options = util["merge"](candran["default"], options) -- candran.can:231 +local ast, errmsg = parser["parse"](input, options["chunkname"]) -- candran.can:233 +if not ast then -- candran.can:235 +return nil, errmsg -- candran.can:236 +end -- candran.can:236 +return require("compiler." .. options["target"])(input, ast, options, macros) -- candran.can:239 +end -- candran.can:239 +candran["make"] = function(code, options) -- candran.can:248 +local r, err = candran["preprocess"](code, options) -- candran.can:249 if r then -- candran.can:250 -return r -- candran.can:251 -end -- candran.can:251 -end -- candran.can:251 -return r, err -- candran.can:254 -end -- candran.can:254 -local errorRewritingActive = false -- candran.can:257 -local codeCache = {} -- candran.can:258 -candran["loadfile"] = function(filepath, env, options) -- candran.can:261 -local f, err = io["open"](filepath) -- candran.can:262 -if not f then -- candran.can:263 -return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:264 -end -- candran.can:264 -local content = f:read("*a") -- candran.can:266 -f:close() -- candran.can:267 -return candran["load"](content, filepath, env, options) -- candran.can:269 -end -- candran.can:269 -candran["load"] = function(chunk, chunkname, env, options) -- candran.can:274 -if options == nil then options = {} end -- candran.can:274 -options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:275 -local code, err = candran["make"](chunk, options) -- candran.can:277 -if not code then -- candran.can:278 -return code, err -- candran.can:279 -end -- candran.can:279 -codeCache[options["chunkname"]] = code -- candran.can:282 -local f -- candran.can:283 -f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:284 -if f == nil then -- candran.can:289 -return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:290 -end -- candran.can:290 -if options["rewriteErrors"] == false then -- candran.can:293 -return f -- candran.can:294 -else -- candran.can:294 -return function(...) -- candran.can:296 -if not errorRewritingActive then -- candran.can:297 -errorRewritingActive = true -- candran.can:298 -local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:299 -errorRewritingActive = false -- candran.can:300 -if t[1] == false then -- candran.can:301 -error(t[2], 0) -- candran.can:302 -end -- candran.can:302 -return unpack(t, 2) -- candran.can:304 -else -- candran.can:304 -return f(...) -- candran.can:306 -end -- candran.can:306 -end -- candran.can:306 -end -- candran.can:306 -end -- candran.can:306 -candran["dofile"] = function(filename, options) -- candran.can:314 -local f, err = candran["loadfile"](filename, nil, options) -- candran.can:315 -if f == nil then -- candran.can:317 -error(err) -- candran.can:318 -else -- candran.can:318 -return f() -- candran.can:320 -end -- candran.can:320 -end -- candran.can:320 -candran["messageHandler"] = function(message, noTraceback) -- candran.can:326 -message = tostring(message) -- candran.can:327 +r, err = candran["compile"](r, options, err) -- candran.can:251 +if r then -- candran.can:252 +return r -- candran.can:253 +end -- candran.can:253 +end -- candran.can:253 +return r, err -- candran.can:256 +end -- candran.can:256 +local errorRewritingActive = false -- candran.can:259 +local codeCache = {} -- candran.can:260 +candran["loadfile"] = function(filepath, env, options) -- candran.can:263 +local f, err = io["open"](filepath) -- candran.can:264 +if not f then -- candran.can:265 +return nil, ("cannot open %s"):format(tostring(err)) -- candran.can:266 +end -- candran.can:266 +local content = f:read("*a") -- candran.can:268 +f:close() -- candran.can:269 +return candran["load"](content, filepath, env, options) -- candran.can:271 +end -- candran.can:271 +candran["load"] = function(chunk, chunkname, env, options) -- candran.can:276 +if options == nil then options = {} end -- candran.can:276 +options = util["merge"]({ ["chunkname"] = tostring(chunkname or chunk) }, options) -- candran.can:277 +local code, err = candran["make"](chunk, options) -- candran.can:279 +if not code then -- candran.can:280 +return code, err -- candran.can:281 +end -- candran.can:281 +codeCache[options["chunkname"]] = code -- candran.can:284 +local f -- candran.can:285 +f, err = util["load"](code, ("=%s(%s)"):format(options["chunkname"], "compiled candran"), env) -- candran.can:286 +if f == nil then -- candran.can:291 +return f, "candran unexpectedly generated invalid code: " .. err -- candran.can:292 +end -- candran.can:292 +if options["rewriteErrors"] == false then -- candran.can:295 +return f -- candran.can:296 +else -- candran.can:296 +return function(...) -- candran.can:298 +if not errorRewritingActive then -- candran.can:299 +errorRewritingActive = true -- candran.can:300 +local t = { xpcall(f, candran["messageHandler"], ...) } -- candran.can:301 +errorRewritingActive = false -- candran.can:302 +if t[1] == false then -- candran.can:303 +error(t[2], 0) -- candran.can:304 +end -- candran.can:304 +return unpack(t, 2) -- candran.can:306 +else -- candran.can:306 +return f(...) -- candran.can:308 +end -- candran.can:308 +end -- candran.can:308 +end -- candran.can:308 +end -- candran.can:308 +candran["dofile"] = function(filename, options) -- candran.can:316 +local f, err = candran["loadfile"](filename, nil, options) -- candran.can:317 +if f == nil then -- candran.can:319 +error(err) -- candran.can:320 +else -- candran.can:320 +return f() -- candran.can:322 +end -- candran.can:322 +end -- candran.can:322 +candran["messageHandler"] = function(message, noTraceback) -- candran.can:328 +message = tostring(message) -- candran.can:329 if not noTraceback and not message:match("\ stack traceback:\ -") then -- candran.can:328 -message = debug["traceback"](message, 2) -- candran.can:329 -end -- candran.can:329 +") then -- candran.can:330 +message = debug["traceback"](message, 2) -- candran.can:331 +end -- candran.can:331 return message:gsub("(\ ?%s*)([^\ -]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:331 -line = tonumber(line) -- candran.can:332 -local originalFile -- candran.can:334 -local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:335 -if strName then -- candran.can:336 -if codeCache[strName] then -- candran.can:337 -originalFile = codeCache[strName] -- candran.can:338 -source = strName -- candran.can:339 -end -- candran.can:339 -else -- candran.can:339 -do -- candran.can:342 -local fi -- candran.can:342 -fi = io["open"](source, "r") -- candran.can:342 -if fi then -- candran.can:342 -originalFile = fi:read("*a") -- candran.can:343 -fi:close() -- candran.can:344 -end -- candran.can:344 -end -- candran.can:344 -end -- candran.can:344 -if originalFile then -- candran.can:348 -local i = 0 -- candran.can:349 +]-)%:(%d+)%:", function(indentation, source, line) -- candran.can:333 +line = tonumber(line) -- candran.can:334 +local originalFile -- candran.can:336 +local strName = source:match("^(.-)%(compiled candran%)$") -- candran.can:337 +if strName then -- candran.can:338 +if codeCache[strName] then -- candran.can:339 +originalFile = codeCache[strName] -- candran.can:340 +source = strName -- candran.can:341 +end -- candran.can:341 +else -- candran.can:341 +do -- candran.can:344 +local fi -- candran.can:344 +fi = io["open"](source, "r") -- candran.can:344 +if fi then -- candran.can:344 +originalFile = fi:read("*a") -- candran.can:345 +fi:close() -- candran.can:346 +end -- candran.can:346 +end -- candran.can:346 +end -- candran.can:346 +if originalFile then -- candran.can:350 +local i = 0 -- candran.can:351 for l in (originalFile .. "\ "):gmatch("([^\ ]*)\ -") do -- candran.can:350 -i = i + 1 -- candran.can:351 -if i == line then -- candran.can:352 -local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:353 -if lineMap then -- candran.can:354 -if extSource ~= source then -- candran.can:355 -return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:356 -else -- candran.can:356 -return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:358 -end -- candran.can:358 -end -- candran.can:358 -break -- candran.can:361 -end -- candran.can:361 -end -- candran.can:361 -end -- candran.can:361 -end) -- candran.can:361 -end -- candran.can:361 -candran["searcher"] = function(modpath) -- candran.can:369 -local filepath = util["search"](modpath, { "can" }) -- candran.can:370 -if not filepath then -- candran.can:371 -if _VERSION == "Lua 5.4" then -- candran.can:372 -return "no candran file in package.path" -- candran.can:373 -else -- candran.can:373 +") do -- candran.can:352 +i = i + 1 -- candran.can:353 +if i == line then -- candran.can:354 +local extSource, lineMap = l:match(".*%-%- (.-)%:(%d+)$") -- candran.can:355 +if lineMap then -- candran.can:356 +if extSource ~= source then -- candran.can:357 +return indentation .. extSource .. ":" .. lineMap .. "(" .. extSource .. ":" .. line .. "):" -- candran.can:358 +else -- candran.can:358 +return indentation .. extSource .. ":" .. lineMap .. "(" .. line .. "):" -- candran.can:360 +end -- candran.can:360 +end -- candran.can:360 +break -- candran.can:363 +end -- candran.can:363 +end -- candran.can:363 +end -- candran.can:363 +end) -- candran.can:363 +end -- candran.can:363 +candran["searcher"] = function(modpath) -- candran.can:371 +local filepath = util["search"](modpath, { "can" }) -- candran.can:372 +if not filepath then -- candran.can:373 +if _VERSION == "Lua 5.4" then -- candran.can:374 +return "no candran file in package.path" -- candran.can:375 +else -- candran.can:375 return "\ -\9no candran file in package.path" -- candran.can:375 -end -- candran.can:375 -end -- candran.can:375 -return function(modpath) -- candran.can:378 -local r, s = candran["loadfile"](filepath) -- candran.can:379 -if r then -- candran.can:380 -return r(modpath, filepath) -- candran.can:381 -else -- candran.can:381 +\9no candran file in package.path" -- candran.can:377 +end -- candran.can:377 +end -- candran.can:377 +return function(modpath) -- candran.can:380 +local r, s = candran["loadfile"](filepath) -- candran.can:381 +if r then -- candran.can:382 +return r(modpath, filepath) -- candran.can:383 +else -- candran.can:383 error(("error loading candran module '%s' from file '%s':\ -\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:383 -end -- candran.can:383 -end, filepath -- candran.can:385 +\9%s"):format(modpath, filepath, tostring(s)), 0) -- candran.can:385 end -- candran.can:385 -candran["setup"] = function() -- candran.can:389 -local searchers = (function() -- candran.can:390 -if _VERSION == "Lua 5.1" then -- candran.can:390 -return package["loaders"] -- candran.can:391 -else -- candran.can:391 -return package["searchers"] -- candran.can:393 -end -- candran.can:393 -end)() -- candran.can:393 -for _, s in ipairs(searchers) do -- candran.can:396 -if s == candran["searcher"] then -- candran.can:397 -return candran -- candran.can:398 -end -- candran.can:398 -end -- candran.can:398 -table["insert"](searchers, 1, candran["searcher"]) -- candran.can:402 -return candran -- candran.can:403 -end -- candran.can:403 -return candran -- candran.can:406 +end, filepath -- candran.can:387 +end -- candran.can:387 +candran["setup"] = function() -- candran.can:391 +local searchers = (function() -- candran.can:392 +if _VERSION == "Lua 5.1" then -- candran.can:392 +return package["loaders"] -- candran.can:393 +else -- candran.can:393 +return package["searchers"] -- candran.can:395 +end -- candran.can:395 +end)() -- candran.can:395 +for _, s in ipairs(searchers) do -- candran.can:398 +if s == candran["searcher"] then -- candran.can:399 +return candran -- candran.can:400 +end -- candran.can:400 +end -- candran.can:400 +table["insert"](searchers, 1, candran["searcher"]) -- candran.can:404 +return candran -- candran.can:405 +end -- candran.can:405 +return candran -- candran.can:408 From 7b0563b9dce20dc1a915bd201551d5cb6cbb3180 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 15:30:23 +0200 Subject: [PATCH 48/52] Fix can handling of --import --- bin/can | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/can b/bin/can index 8a0fc97..6b62a3f 100644 --- a/bin/can +++ b/bin/can @@ -118,18 +118,20 @@ else print("Candran " .. candran.VERSION .. ", targeting " .. candran.default.target) candran.setup() - -- only perform static imports once, on startup + -- check errors in static import + -- note: static imports will be run every line, as preprocessors macros and constants aren't kept between compilations... do local r, e = candran.load("local _", "stdin") if not r then print("In static import: "..e) + candran.default.import = {} else r, e = pcall(r) if not r then print("In static import: "..e) + candran.default.import = {} end end - candran.default.import = {} end -- REPL loop From f0cacd6f08132f9a46fe1358c0d7f4af44da9161 Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 15:33:04 +0200 Subject: [PATCH 49/52] Update tests --- test/test.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.lua b/test/test.lua index 531df53..e01a4cf 100644 --- a/test/test.lua +++ b/test/test.lua @@ -127,7 +127,7 @@ return a test("preprocessor placeholder function", [[ #placeholder('foo') -]], 5, { foo = "return 5" }) +]], 5, { preprocessorEnv = { foo = "return 5" } }) test("preprocessor options", [[ #if not foo == "sky" then From 7131c5c8b1d85049ebe5ac24e984f0a2fee2a155 Mon Sep 17 00:00:00 2001 From: Reuh Date: Wed, 23 Jun 2021 20:54:02 +0200 Subject: [PATCH 50/52] Candran 1.0.0 --- README.md | 16 ++++++++-------- candran.can | 2 +- candran.lua | 2 +- ....14.0-1.rockspec => candran-1.0.0-1.rockspec} | 7 ++++--- rockspec/candran-scm-1.rockspec | 3 +-- 5 files changed, 15 insertions(+), 15 deletions(-) rename rockspec/{candran-0.14.0-1.rockspec => candran-1.0.0-1.rockspec} (92%) diff --git a/README.md b/README.md index 78adb83..c708f6b 100644 --- a/README.md +++ b/README.md @@ -6,19 +6,19 @@ Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing L ````lua #import("lib.thing") -- static import -#local debug = false +#local DEBUG = false -#if debug then -# define("log(...)", "print(...)") +#if DEBUG then +# define("log(...)", "print(...)") -- macro: calls to log() will be replaced with print() in compiled code #else -# define("log(...)", "") -- remove calls to log from the compiled code when debug is true +# define("log(...)", "") -- remove calls to log from the compiled code when DEBUG is true #end log("example macro") -- preprocessor macros local function calculate(toadd=25) -- default parameters local result = thing.do() result += toadd - #if debug then -- preprocessor conditionals + #if DEBUG then -- preprocessor conditionals print("Did something") #end return result @@ -83,7 +83,7 @@ Candran is released under the MIT License (see ```LICENSE``` for details). #### Quick setup Install Candran automatically using LuaRocks: ```sudo luarocks install candran```. -Or manually install LPegLabel (```luarocks install lpeglabel```, version 1.5 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. +Or manually install LPegLabel and argparse (```luarocks install lpeglabel```, version 1.5 or above, and ```luarocks install argparse```, version 0.7 or above), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```. You can optionally install lua-linenoise (```luarocks install linenoise```, version 0.9 or above) for an improved REPL, and luacheck (```luarocks install luacheck```, version 0.23.0 or above) to be able to use ```cancheck```. Installing Candran using LuaRocks will install linenoise and luacheck by default. @@ -449,7 +449,7 @@ Will output ````print("Bonjour")```` or ````print("Hello")```` depending of the The preprocessor has access to the following variables: * ````candran````: the Candran library table. * ````output````: the current preprocessor output string. Can be redefined at any time. If you want to write something in the preprocessor output, it is preferred to use `write(...)` instead of directly modifying `output`. -* ````import(module[, [options])````: a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: +* ````import(module[, [options])````: a function which import a module. This should be equivalent to using _require(module)_ in the Candran code, except the module will be embedded in the current file. Macros and preprocessor constants defined in the imported file (using `define` and `set`) will be made available in the current file. _options_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). Options specific to this function: * ```loadLocal``` (default ```true```): ```true``` to automatically load the module into a local variable (i.e. ```local thing = require("module.thing")```) * ```loadPackage``` (default ```true```): ```true``` to automatically load the module into the loaded packages table (so it will be available for following ```require("module")``` calls). * ````include(filename)````: a function which copy the contents of the file _filename_ to the output. @@ -616,7 +616,7 @@ local f = io.open("foo.can") -- read the file foo.can local contents = f:read("*a") f:close() -local compiled = candran.make(contents, { debug = true }) -- compile foo.can with debug set to true +local compiled = candran.make(contents, { DEBUG = true }) -- compile foo.can with DEBUG set to true load(compiled)() -- execute! diff --git a/candran.can b/candran.can index aee5c57..78a7be4 100644 --- a/candran.can +++ b/candran.can @@ -1,5 +1,5 @@ local candran = { - VERSION = "0.14.0" + VERSION = "1.0.0" } package.loaded["candran"] = candran diff --git a/candran.lua b/candran.lua index 4df71ec..f3945ad 100644 --- a/candran.lua +++ b/candran.lua @@ -1,4 +1,4 @@ -local candran = { ["VERSION"] = "0.14.0" } -- candran.can:2 +local candran = { ["VERSION"] = "1.0.0" } -- candran.can:2 package["loaded"]["candran"] = candran -- candran.can:4 local function _() -- candran.can:7 local candran = require("candran") -- ./candran/util.can:1 diff --git a/rockspec/candran-0.14.0-1.rockspec b/rockspec/candran-1.0.0-1.rockspec similarity index 92% rename from rockspec/candran-0.14.0-1.rockspec rename to rockspec/candran-1.0.0-1.rockspec index dc82cd2..d291e73 100644 --- a/rockspec/candran-0.14.0-1.rockspec +++ b/rockspec/candran-1.0.0-1.rockspec @@ -2,7 +2,7 @@ rockspec_format = "3.0" package = "candran" -version = "0.14.0-1" +version = "1.0.0-1" description = { summary = "A simple Lua dialect and preprocessor.", @@ -19,14 +19,15 @@ description = { source = { url = "git://github.com/Reuh/candran", - tag = "v0.14.0" + tag = "v1.0.0" } dependencies = { "lua >= 5.1", "lpeglabel >= 1.5.0", "linenoise >= 0.9", - "luacheck >= 0.23.0" + "luacheck >= 0.23.0", + "argparse >= 0.7.0" } build = { diff --git a/rockspec/candran-scm-1.rockspec b/rockspec/candran-scm-1.rockspec index 71ce00b..27d40b5 100644 --- a/rockspec/candran-scm-1.rockspec +++ b/rockspec/candran-scm-1.rockspec @@ -18,8 +18,7 @@ description = { } source = { - url = "git://github.com/Reuh/candran", - branch = "argparse" + url = "git://github.com/Reuh/candran" } dependencies = { From 1e118381f8276fe66a2cad02f1b9f4535e7e253e Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 24 Dec 2021 00:05:53 +0100 Subject: [PATCH 51/52] Ignore shadowing warning in cancheck for temporary Candran variables --- bin/cancheck | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/cancheck b/bin/cancheck index d9d3dcc..1d3950f 100644 --- a/bin/cancheck +++ b/bin/cancheck @@ -181,6 +181,7 @@ local oldRunner = runner.new function runner.new(opts) -- Disable max line length checking (it is compiled code...) opts.max_line_length = false + opts.ignore = { "4[23]1/__CAN_.*" } return oldRunner(opts) end From 8d9a79c47dc7ad33bb2faaac6ff9df62e0a19cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Fildadut?= Date: Sun, 22 Dec 2024 16:29:26 +0100 Subject: [PATCH 52/52] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c708f6b..76bd1bd 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Most editors should be able to use their existing Lua support for Candran code. * [sublime-candran](https://github.com/Reuh/sublime-candran) support the full Candran syntax * [SublimeLinter-cancheck-contrib](https://github.com/Reuh/SublimeLinter-contrib-cancheck) SublimeLinter plugin for Candran using ```cancheck``` * [SublimeLinter-candran-contrib](https://github.com/Reuh/SublimeLinter-contrib-candran) SublimeLinter plugin for Candran using ```canc -parse``` (only checks for syntaxic errors, no linting) +* **VS Code**: [vscode-candran](https://github.com/Reuh/vscode-candran) basic support for the Candran syntax * **Atom**: [language-candran](https://atom.io/packages/language-candran) support the full Candran syntax For linting, if your editor support [luacheck](https://github.com/luarocks/luacheck), you should be able to replace it with ```cancheck``` (in this repository ```bin/cancheck```, or installed automatically if Candran was installed using LuaRocks), which is a wrapper around luacheck that monkey-patch it to support Candran.