mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 09:59:29 +00:00
0.5.0
Fixed plenty of bugs. Tests are lacking.
This commit is contained in:
parent
6b95bfb698
commit
d249c353c5
7 changed files with 315 additions and 95 deletions
|
|
@ -46,13 +46,15 @@ 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.requirePrefix .. 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
|
||||
-- Returns the required module variable name.
|
||||
local function getRequire(name)
|
||||
return options.requirePrefix .. name
|
||||
|
||||
--- Variable management
|
||||
-- Returns the prefixed variable name.
|
||||
local function var(name)
|
||||
return options.variablePrefix .. name
|
||||
end
|
||||
|
||||
--- AST traversal helpers
|
||||
|
|
@ -112,18 +114,27 @@ return function(code, ast, options)
|
|||
end
|
||||
return tags[forceTag or ast.tag](ast, ...)
|
||||
end
|
||||
-- Tag constructors
|
||||
|
||||
--- 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 a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end"
|
||||
end
|
||||
|
||||
--- Tag constructors
|
||||
tags = setmetatable({
|
||||
-- block: { stat* } --
|
||||
Block = (t)
|
||||
local hasPush = not peek("push") and any(t, { "Push" }, func) -- push in block and push context not yet defined
|
||||
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 = ""
|
||||
if hasPush then
|
||||
r ..= push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline()
|
||||
r ..= push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()
|
||||
end
|
||||
for i=1, #t-1, 1 do
|
||||
r ..= lua(t[i]) .. newline()
|
||||
|
|
@ -132,7 +143,7 @@ return function(code, ast, options)
|
|||
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(__PUSH__)" .. pop("push")
|
||||
r ..= newline() .. "return " .. UNPACK(var("push")) .. pop("push")
|
||||
end
|
||||
return r
|
||||
end,
|
||||
|
|
@ -291,7 +302,7 @@ return function(code, ast, options)
|
|||
for _, val in ipairs(t) do
|
||||
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
|
||||
|
|
@ -299,7 +310,18 @@ return function(code, ast, options)
|
|||
-- Push{ <expr*> }
|
||||
Push = (t)
|
||||
local var = assert(peek("push"), "no context given for push")
|
||||
return var .. "[#" .. var .. "+1] = " .. lua(t, "_lhs")
|
||||
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" or t[#t].tag == "Invoke" then
|
||||
r ..= APPEND(var, lua(t[#t]))
|
||||
else
|
||||
r ..= var .. "[#" .. var .. "+1] = " .. lua(t[#t])
|
||||
end
|
||||
end
|
||||
return r
|
||||
end,
|
||||
-- Break
|
||||
Break = ()
|
||||
|
|
@ -363,7 +385,21 @@ return function(code, ast, options)
|
|||
for _, d in ipairs(decl) do
|
||||
r ..= d .. newline()
|
||||
end
|
||||
return r .. lua(t[2]) .. unindent() .. "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 don't affect us)
|
||||
end
|
||||
r ..= lua(t[2])
|
||||
if hasPush then
|
||||
r ..= newline() .. "return " .. UNPACK(var("push"))
|
||||
end
|
||||
pop("push")
|
||||
return r .. unindent() .. "end"
|
||||
end,
|
||||
Function = (t)
|
||||
return "function" .. lua(t, "_functionWithoutKeyword")
|
||||
|
|
@ -416,12 +452,15 @@ return function(code, ast, options)
|
|||
local hasPush = any(t, { "Push" }, func)
|
||||
local r = "(function()" .. indent()
|
||||
if hasPush then
|
||||
r ..= push("push", "__PUSH__") .. "local __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(__PUSH__)" .. pop("push")
|
||||
r ..= newline() .. "return " .. UNPACK(var("push"))
|
||||
end
|
||||
pop("push")
|
||||
r ..= unindent() .. "end)()"
|
||||
return r
|
||||
end,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,34 @@
|
|||
tags._opid.idiv = function(left, right)
|
||||
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"
|
||||
end
|
||||
|
||||
tags._opid.idiv = (left, right)
|
||||
return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.band = function(left, right)
|
||||
tags._opid.band = (left, right)
|
||||
addRequire("bit", "band", "band")
|
||||
return getRequire("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.bor = function(left, right)
|
||||
tags._opid.bor = (left, right)
|
||||
addRequire("bit", "bor", "bor")
|
||||
return getRequire("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.bxor = function(left, right)
|
||||
tags._opid.bxor = (left, right)
|
||||
addRequire("bit", "bxor", "bxor")
|
||||
return getRequire("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.shl = function(left, right)
|
||||
tags._opid.shl = (left, right)
|
||||
addRequire("bit", "lshift", "lshift")
|
||||
return getRequire("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.shr = function(left, right)
|
||||
tags._opid.shr = (left, right)
|
||||
addRequire("bit", "rshift", "rshift")
|
||||
return getRequire("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||
end
|
||||
tags._opid.bnot = function(right)
|
||||
tags._opid.bnot = (right)
|
||||
addRequire("bit", "bnot", "bnot")
|
||||
return getRequire("bnot") .. "(" .. lua(right) .. ")"
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue