mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 17:59:30 +00:00
Added let and continue
This commit is contained in:
parent
5194cfb115
commit
c0f7934d92
10 changed files with 316 additions and 119 deletions
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright 2017 Étienne "Reuh" Fildadut
|
Copyright (c) 2017 É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:
|
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:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,9 @@ end)
|
||||||
````
|
````
|
||||||
|
|
||||||
#### Quick setup
|
#### Quick setup
|
||||||
Install LPegLabel (```luarocks install LPegLabel```), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```.
|
Install Candran automatically using LuaRocks: ```sudo luarocks install candran```.
|
||||||
|
|
||||||
|
Or manually install LPegLabel (```luarocks install LPegLabel```), download this repository and use Candran through the scripts in ```bin/``` or use it as a library with the self-contained ```candran.lua```.
|
||||||
|
|
||||||
The language
|
The language
|
||||||
------------
|
------------
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#import("lib.lua-parser.parser")
|
#import("lib.lua-parser.parser")
|
||||||
|
|
||||||
local candran = {
|
local candran = {
|
||||||
VERSION = "0.3.1"
|
VERSION = "0.4.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Default options.
|
--- Default options.
|
||||||
|
|
|
||||||
141
candran.lua
141
candran.lua
|
|
@ -168,15 +168,35 @@ return newline()
|
||||||
end
|
end
|
||||||
local required = {}
|
local required = {}
|
||||||
local requireStr = ""
|
local requireStr = ""
|
||||||
local function addRequire(str, name, field)
|
local function addRequire(mod, name, field)
|
||||||
if not required[str] then
|
if not required[mod] then
|
||||||
requireStr = requireStr .. "local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(str) .. (field and "." .. field or "") .. options["newline"]
|
requireStr = requireStr .. "local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]
|
||||||
required[str] = true
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function getRequire(name)
|
local function getRequire(name)
|
||||||
return options["requirePrefix"] .. name
|
return options["requirePrefix"] .. name
|
||||||
end
|
end
|
||||||
|
local function any(list, tags)
|
||||||
|
local tagsCheck = {}
|
||||||
|
for _, tag in ipairs(tags) do
|
||||||
|
tagsCheck[tag] = true
|
||||||
|
end
|
||||||
|
for _, node in ipairs(list) do
|
||||||
|
if tagsCheck[node["tag"]] then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local namedNodes = {}
|
||||||
|
local function wrap(name, prefix, suffix)
|
||||||
|
local node = namedNodes[name]
|
||||||
|
if not node then
|
||||||
|
error("not inside a " .. name)
|
||||||
|
end
|
||||||
|
node["prefix"], node["suffix"] = prefix .. newline(), newline() .. suffix
|
||||||
|
end
|
||||||
local tags
|
local tags
|
||||||
local function lua(ast, forceTag, ...)
|
local function lua(ast, forceTag, ...)
|
||||||
if options["mapLines"] and ast["pos"] then
|
if options["mapLines"] and ast["pos"] then
|
||||||
|
|
@ -184,6 +204,13 @@ lastInputPos = ast["pos"]
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast["tag"]](ast, ...)
|
return tags[forceTag or ast["tag"]](ast, ...)
|
||||||
end
|
end
|
||||||
|
local function namedLua(name, ast, ...)
|
||||||
|
local old = namedNodes[name]
|
||||||
|
namedNodes[name] = ast
|
||||||
|
local code = lua(ast, ...)
|
||||||
|
namedNodes[name] = old
|
||||||
|
return (ast["prefix"] or "") .. code .. (ast["suffix"] or "")
|
||||||
|
end
|
||||||
tags = setmetatable({
|
tags = setmetatable({
|
||||||
["Block"] = function(t)
|
["Block"] = function(t)
|
||||||
local r = ""
|
local r = ""
|
||||||
|
|
@ -239,9 +266,9 @@ end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
end, ["While"] = function(t)
|
end, ["While"] = function(t)
|
||||||
return "while " .. lua(t[1]) .. " do" .. indent() .. lua(t[2]) .. unindent() .. "end"
|
return "while " .. lua(t[1]) .. " do" .. indent() .. namedLua("loop", t[2]) .. unindent() .. "end"
|
||||||
end, ["Repeat"] = function(t)
|
end, ["Repeat"] = function(t)
|
||||||
return "repeat" .. indent() .. lua(t[1]) .. unindent() .. "until " .. lua(t[2])
|
return "repeat" .. indent() .. namedLua("loop", t[1]) .. unindent() .. "until " .. lua(t[2])
|
||||||
end, ["If"] = function(t)
|
end, ["If"] = function(t)
|
||||||
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
||||||
for i = 3, # t - 1, 2 do
|
for i = 3, # t - 1, 2 do
|
||||||
|
|
@ -256,16 +283,29 @@ local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3])
|
||||||
if # t == 5 then
|
if # t == 5 then
|
||||||
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
||||||
else
|
else
|
||||||
return r .. " do" .. indent() .. lua(t[4]) .. unindent() .. "end"
|
return r .. " do" .. indent() .. namedLua("loop", t[4]) .. unindent() .. "end"
|
||||||
end
|
end
|
||||||
end, ["Forin"] = function(t)
|
end, ["Forin"] = function(t)
|
||||||
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. lua(t[3]) .. unindent() .. "end"
|
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. namedLua("loop", t[3]) .. unindent() .. "end"
|
||||||
end, ["Local"] = function(t)
|
end, ["Local"] = function(t)
|
||||||
local r = "local " .. lua(t[1], "_lhs")
|
local r = "local " .. lua(t[1], "_lhs")
|
||||||
if t[2][1] then
|
if t[2][1] then
|
||||||
r = r .. " = " .. lua(t[2], "_lhs")
|
r = r .. " = " .. lua(t[2], "_lhs")
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
|
end, ["Let"] = function(t)
|
||||||
|
local nameList = lua(t[1], "_lhs")
|
||||||
|
local r = "local " .. nameList
|
||||||
|
if t[2][1] then
|
||||||
|
if any(t[2], {
|
||||||
|
"Function", "Table", "Paren"
|
||||||
|
}) then
|
||||||
|
r = r .. newline() .. nameList .. " = " .. lua(t[2], "_lhs")
|
||||||
|
else
|
||||||
|
r = r .. " = " .. lua(t[2], "_lhs")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r
|
||||||
end, ["Localrec"] = function(t)
|
end, ["Localrec"] = function(t)
|
||||||
return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword")
|
return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword")
|
||||||
end, ["Goto"] = function(t)
|
end, ["Goto"] = function(t)
|
||||||
|
|
@ -276,6 +316,9 @@ end, ["Return"] = function(t)
|
||||||
return "return " .. lua(t, "_lhs")
|
return "return " .. lua(t, "_lhs")
|
||||||
end, ["Break"] = function()
|
end, ["Break"] = function()
|
||||||
return "break"
|
return "break"
|
||||||
|
end, ["Continue"] = function()
|
||||||
|
wrap("loop", "repeat", "until true")
|
||||||
|
return "break"
|
||||||
end, ["Nil"] = function()
|
end, ["Nil"] = function()
|
||||||
return "nil"
|
return "nil"
|
||||||
end, ["Dots"] = function()
|
end, ["Dots"] = function()
|
||||||
|
|
@ -372,7 +415,8 @@ end, ["_opid"] = {
|
||||||
}, { ["__index"] = function(self, key)
|
}, { ["__index"] = function(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 Lua 5.3")
|
||||||
end })
|
end })
|
||||||
return requireStr .. lua(ast) .. newline()
|
local code = lua(ast) .. newline()
|
||||||
|
return requireStr .. code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local lua53 = _() or lua53
|
local lua53 = _() or lua53
|
||||||
|
|
@ -416,15 +460,35 @@ return newline()
|
||||||
end
|
end
|
||||||
local required = {}
|
local required = {}
|
||||||
local requireStr = ""
|
local requireStr = ""
|
||||||
local function addRequire(str, name, field)
|
local function addRequire(mod, name, field)
|
||||||
if not required[str] then
|
if not required[mod] then
|
||||||
requireStr = requireStr .. "local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(str) .. (field and "." .. field or "") .. options["newline"]
|
requireStr = requireStr .. "local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"]
|
||||||
required[str] = true
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function getRequire(name)
|
local function getRequire(name)
|
||||||
return options["requirePrefix"] .. name
|
return options["requirePrefix"] .. name
|
||||||
end
|
end
|
||||||
|
local function any(list, tags)
|
||||||
|
local tagsCheck = {}
|
||||||
|
for _, tag in ipairs(tags) do
|
||||||
|
tagsCheck[tag] = true
|
||||||
|
end
|
||||||
|
for _, node in ipairs(list) do
|
||||||
|
if tagsCheck[node["tag"]] then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local namedNodes = {}
|
||||||
|
local function wrap(name, prefix, suffix)
|
||||||
|
local node = namedNodes[name]
|
||||||
|
if not node then
|
||||||
|
error("not inside a " .. name)
|
||||||
|
end
|
||||||
|
node["prefix"], node["suffix"] = prefix .. newline(), newline() .. suffix
|
||||||
|
end
|
||||||
local tags
|
local tags
|
||||||
local function lua(ast, forceTag, ...)
|
local function lua(ast, forceTag, ...)
|
||||||
if options["mapLines"] and ast["pos"] then
|
if options["mapLines"] and ast["pos"] then
|
||||||
|
|
@ -432,6 +496,13 @@ lastInputPos = ast["pos"]
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast["tag"]](ast, ...)
|
return tags[forceTag or ast["tag"]](ast, ...)
|
||||||
end
|
end
|
||||||
|
local function namedLua(name, ast, ...)
|
||||||
|
local old = namedNodes[name]
|
||||||
|
namedNodes[name] = ast
|
||||||
|
local code = lua(ast, ...)
|
||||||
|
namedNodes[name] = old
|
||||||
|
return (ast["prefix"] or "") .. code .. (ast["suffix"] or "")
|
||||||
|
end
|
||||||
tags = setmetatable({
|
tags = setmetatable({
|
||||||
["Block"] = function(t)
|
["Block"] = function(t)
|
||||||
local r = ""
|
local r = ""
|
||||||
|
|
@ -487,9 +558,9 @@ end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
end, ["While"] = function(t)
|
end, ["While"] = function(t)
|
||||||
return "while " .. lua(t[1]) .. " do" .. indent() .. lua(t[2]) .. unindent() .. "end"
|
return "while " .. lua(t[1]) .. " do" .. indent() .. namedLua("loop", t[2]) .. unindent() .. "end"
|
||||||
end, ["Repeat"] = function(t)
|
end, ["Repeat"] = function(t)
|
||||||
return "repeat" .. indent() .. lua(t[1]) .. unindent() .. "until " .. lua(t[2])
|
return "repeat" .. indent() .. namedLua("loop", t[1]) .. unindent() .. "until " .. lua(t[2])
|
||||||
end, ["If"] = function(t)
|
end, ["If"] = function(t)
|
||||||
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
||||||
for i = 3, # t - 1, 2 do
|
for i = 3, # t - 1, 2 do
|
||||||
|
|
@ -504,16 +575,29 @@ local r = "for " .. lua(t[1]) .. " = " .. lua(t[2]) .. ", " .. lua(t[3])
|
||||||
if # t == 5 then
|
if # t == 5 then
|
||||||
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
||||||
else
|
else
|
||||||
return r .. " do" .. indent() .. lua(t[4]) .. unindent() .. "end"
|
return r .. " do" .. indent() .. namedLua("loop", t[4]) .. unindent() .. "end"
|
||||||
end
|
end
|
||||||
end, ["Forin"] = function(t)
|
end, ["Forin"] = function(t)
|
||||||
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. lua(t[3]) .. unindent() .. "end"
|
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. namedLua("loop", t[3]) .. unindent() .. "end"
|
||||||
end, ["Local"] = function(t)
|
end, ["Local"] = function(t)
|
||||||
local r = "local " .. lua(t[1], "_lhs")
|
local r = "local " .. lua(t[1], "_lhs")
|
||||||
if t[2][1] then
|
if t[2][1] then
|
||||||
r = r .. " = " .. lua(t[2], "_lhs")
|
r = r .. " = " .. lua(t[2], "_lhs")
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
|
end, ["Let"] = function(t)
|
||||||
|
local nameList = lua(t[1], "_lhs")
|
||||||
|
local r = "local " .. nameList
|
||||||
|
if t[2][1] then
|
||||||
|
if any(t[2], {
|
||||||
|
"Function", "Table", "Paren"
|
||||||
|
}) then
|
||||||
|
r = r .. newline() .. nameList .. " = " .. lua(t[2], "_lhs")
|
||||||
|
else
|
||||||
|
r = r .. " = " .. lua(t[2], "_lhs")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r
|
||||||
end, ["Localrec"] = function(t)
|
end, ["Localrec"] = function(t)
|
||||||
return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword")
|
return "local function " .. lua(t[1][1]) .. lua(t[2][1], "_functionWithoutKeyword")
|
||||||
end, ["Goto"] = function(t)
|
end, ["Goto"] = function(t)
|
||||||
|
|
@ -524,6 +608,9 @@ end, ["Return"] = function(t)
|
||||||
return "return " .. lua(t, "_lhs")
|
return "return " .. lua(t, "_lhs")
|
||||||
end, ["Break"] = function()
|
end, ["Break"] = function()
|
||||||
return "break"
|
return "break"
|
||||||
|
end, ["Continue"] = function()
|
||||||
|
wrap("loop", "repeat", "until true")
|
||||||
|
return "break"
|
||||||
end, ["Nil"] = function()
|
end, ["Nil"] = function()
|
||||||
return "nil"
|
return "nil"
|
||||||
end, ["Dots"] = function()
|
end, ["Dots"] = function()
|
||||||
|
|
@ -647,7 +734,8 @@ tags["_opid"]["bnot"] = function(right)
|
||||||
addRequire("bit", "bnot", "bnot")
|
addRequire("bit", "bnot", "bnot")
|
||||||
return getRequire("bnot") .. "(" .. lua(right) .. ")"
|
return getRequire("bnot") .. "(" .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
return requireStr .. lua(ast) .. newline()
|
local code = lua(ast) .. newline()
|
||||||
|
return requireStr .. code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local lua53 = _() or lua53
|
local lua53 = _() or lua53
|
||||||
|
|
@ -898,6 +986,13 @@ return nil, syntaxerror(env["errorinfo"], stm["pos"], msg)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
local function traverse_continue(env, stm)
|
||||||
|
if not insideloop(env) then
|
||||||
|
local msg = "<continue> not inside a loop"
|
||||||
|
return nil, syntaxerror(env["errorinfo"], stm["pos"], msg)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
local function traverse_forin(env, stm)
|
local function traverse_forin(env, stm)
|
||||||
begin_loop(env)
|
begin_loop(env)
|
||||||
new_scope(env)
|
new_scope(env)
|
||||||
|
|
@ -1112,7 +1207,7 @@ elseif tag == "Fornum" then
|
||||||
return traverse_fornum(env, stm)
|
return traverse_fornum(env, stm)
|
||||||
elseif tag == "Forin" then
|
elseif tag == "Forin" then
|
||||||
return traverse_forin(env, stm)
|
return traverse_forin(env, stm)
|
||||||
elseif tag == "Local" then
|
elseif tag == "Local" or tag == "Let" then
|
||||||
return traverse_let(env, stm)
|
return traverse_let(env, stm)
|
||||||
elseif tag == "Localrec" then
|
elseif tag == "Localrec" then
|
||||||
return traverse_letrec(env, stm)
|
return traverse_letrec(env, stm)
|
||||||
|
|
@ -1124,6 +1219,8 @@ elseif tag == "Return" then
|
||||||
return traverse_return(env, stm)
|
return traverse_return(env, stm)
|
||||||
elseif tag == "Break" then
|
elseif tag == "Break" then
|
||||||
return traverse_break(env, stm)
|
return traverse_break(env, stm)
|
||||||
|
elseif tag == "Continue" then
|
||||||
|
return traverse_continue(env, stm)
|
||||||
elseif tag == "Call" then
|
elseif tag == "Call" then
|
||||||
return traverse_call(env, stm)
|
return traverse_call(env, stm)
|
||||||
elseif tag == "Invoke" then
|
elseif tag == "Invoke" then
|
||||||
|
|
@ -1552,6 +1649,8 @@ local labels = {
|
||||||
}, {
|
}, {
|
||||||
"ErrDefLocal", "expected a function definition or assignment after local"
|
"ErrDefLocal", "expected a function definition or assignment after local"
|
||||||
}, {
|
}, {
|
||||||
|
"ErrDefLet", "expected a function definition or assignment after let"
|
||||||
|
}, {
|
||||||
"ErrNameLFunc", "expected a function name after 'function'"
|
"ErrNameLFunc", "expected a function name after 'function'"
|
||||||
}, {
|
}, {
|
||||||
"ErrEListLAssign", "expected one or more expressions after '='"
|
"ErrEListLAssign", "expected one or more expressions after '='"
|
||||||
|
|
@ -1766,7 +1865,7 @@ return t1
|
||||||
end
|
end
|
||||||
local G = {
|
local G = {
|
||||||
V("Lua"), ["Lua"] = V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra"), ["Shebang"] = P("#!") * (P(1) - P("\
|
V("Lua"), ["Lua"] = V("Shebang") ^ - 1 * V("Skip") * V("Block") * expect(P(- 1), "Extra"), ["Shebang"] = P("#!") * (P(1) - P("\
|
||||||
")) ^ 0, ["Block"] = tagC("Block", V("Stat") ^ 0 * V("RetStat") ^ - 1), ["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") + sym(";") + - V("BlockEnd") * throw("InvalidStat"), ["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + - 1, ["IfStat"] = tagC("If", V("IfPart") * V("ElseIfPart") ^ 0 * V("ElsePart") ^ - 1 * expect(kw("end"), "EndIf")), ["IfPart"] = kw("if") * expect(V("Expr"), "ExprIf") * expect(kw("then"), "ThenIf") * V("Block"), ["ElseIfPart"] = kw("elseif") * expect(V("Expr"), "ExprEIf") * expect(kw("then"), "ThenEIf") * V("Block"), ["ElsePart"] = kw("else") * V("Block"), ["DoStat"] = kw("do") * V("Block") * expect(kw("end"), "EndDo") / tagDo, ["WhileStat"] = tagC("While", kw("while") * expect(V("Expr"), "ExprWhile") * V("WhileBody")), ["WhileBody"] = expect(kw("do"), "DoWhile") * V("Block") * expect(kw("end"), "EndWhile"), ["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), ["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange") * expect(kw("end"), "EndFor"), ["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")), ["ForBody"] = expect(kw("do"), "DoFor") * V("Block"), ["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()))), ["Assignment"] = tagC("Set", V("VarList") * V("BinOp") ^ - 1 * (sym("=") / "=") * V("BinOp") ^ - 1 * 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) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, ["FuncBody"] = tagC("Function", V("FuncParams") * V("Block") * expect(kw("end"), "EndFunc")), ["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), ["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), ["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), ["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), ["ParKey"] = V("Id") * # ("=" * - P("=")), ["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), ["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), ["BreakStat"] = tagC("Break", kw("break")), ["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1 * sym(";") ^ - 1), ["NameList"] = tagC("NameList", commaSep(V("Id"))), ["VarList"] = tagC("VarList", commaSep(V("VarExpr"), "VarList")), ["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), ["Expr"] = V("OrExpr"), ["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), ["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), ["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), ["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), ["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), ["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), ["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), ["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, ["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), ["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), ["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("String", V("String")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + V("Table") + V("SuffixedExpr"), ["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp)
|
")) ^ 0, ["Block"] = tagC("Block", V("Stat") ^ 0 * V("RetStat") ^ - 1), ["Stat"] = V("IfStat") + V("DoStat") + V("WhileStat") + V("RepeatStat") + V("ForStat") + V("LocalStat") + V("LetStat") + V("FuncStat") + V("BreakStat") + V("ContinueStat") + V("LabelStat") + V("GoToStat") + V("FuncCall") + V("Assignment") + sym(";") + - V("BlockEnd") * throw("InvalidStat"), ["BlockEnd"] = P("return") + "end" + "elseif" + "else" + "until" + - 1, ["IfStat"] = tagC("If", V("IfPart") * V("ElseIfPart") ^ 0 * V("ElsePart") ^ - 1 * expect(kw("end"), "EndIf")), ["IfPart"] = kw("if") * expect(V("Expr"), "ExprIf") * expect(kw("then"), "ThenIf") * V("Block"), ["ElseIfPart"] = kw("elseif") * expect(V("Expr"), "ExprEIf") * expect(kw("then"), "ThenEIf") * V("Block"), ["ElsePart"] = kw("else") * V("Block"), ["DoStat"] = kw("do") * V("Block") * expect(kw("end"), "EndDo") / tagDo, ["WhileStat"] = tagC("While", kw("while") * expect(V("Expr"), "ExprWhile") * V("WhileBody")), ["WhileBody"] = expect(kw("do"), "DoWhile") * V("Block") * expect(kw("end"), "EndWhile"), ["RepeatStat"] = tagC("Repeat", kw("repeat") * V("Block") * expect(kw("until"), "UntilRep") * expect(V("Expr"), "ExprRep")), ["ForStat"] = kw("for") * expect(V("ForNum") + V("ForIn"), "ForRange") * expect(kw("end"), "EndFor"), ["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")), ["ForBody"] = expect(kw("do"), "DoFor") * V("Block"), ["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()))), ["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 * (sym("=") / "=") * V("BinOp") ^ - 1 * 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) * (sym(":") * expect(V("StrId"), "NameFunc2")) ^ - 1 / markMethod, ["FuncBody"] = tagC("Function", V("FuncParams") * V("Block") * expect(kw("end"), "EndFunc")), ["FuncParams"] = expect(sym("("), "OParenPList") * V("ParList") * expect(sym(")"), "CParenPList"), ["ParList"] = V("NamedParList") * (sym(",") * expect(tagC("Dots", sym("...")), "ParList")) ^ - 1 / addDots + Ct(tagC("Dots", sym("..."))) + Ct(Cc()), ["NamedParList"] = tagC("NamedParList", commaSep(V("NamedPar"))), ["NamedPar"] = tagC("ParPair", V("ParKey") * expect(sym("="), "EqField") * expect(V("Expr"), "ExprField")) + V("Id"), ["ParKey"] = V("Id") * # ("=" * - P("=")), ["LabelStat"] = tagC("Label", sym("::") * expect(V("Name"), "Label") * expect(sym("::"), "CloseLabel")), ["GoToStat"] = tagC("Goto", kw("goto") * expect(V("Name"), "Goto")), ["BreakStat"] = tagC("Break", kw("break")), ["ContinueStat"] = tagC("Continue", kw("continue")), ["RetStat"] = tagC("Return", kw("return") * commaSep(V("Expr"), "RetList") ^ - 1 * sym(";") ^ - 1), ["NameList"] = tagC("NameList", commaSep(V("Id"))), ["VarList"] = tagC("VarList", commaSep(V("VarExpr"), "VarList")), ["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), ["Expr"] = V("OrExpr"), ["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), ["AndExpr"] = chainOp(V("RelExpr"), V("AndOp"), "AndExpr"), ["RelExpr"] = chainOp(V("BOrExpr"), V("RelOp"), "RelExpr"), ["BOrExpr"] = chainOp(V("BXorExpr"), V("BOrOp"), "BOrExpr"), ["BXorExpr"] = chainOp(V("BAndExpr"), V("BXorOp"), "BXorExpr"), ["BAndExpr"] = chainOp(V("ShiftExpr"), V("BAndOp"), "BAndExpr"), ["ShiftExpr"] = chainOp(V("ConcatExpr"), V("ShiftOp"), "ShiftExpr"), ["ConcatExpr"] = V("AddExpr") * (V("ConcatOp") * expect(V("ConcatExpr"), "ConcatExpr")) ^ - 1 / binaryOp, ["AddExpr"] = chainOp(V("MulExpr"), V("AddOp"), "AddExpr"), ["MulExpr"] = chainOp(V("UnaryExpr"), V("MulOp"), "MulExpr"), ["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("String", V("String")) + tagC("Nil", kw("nil")) + tagC("Boolean", kw("false") * Cc(false)) + tagC("Boolean", kw("true") * Cc(true)) + tagC("Dots", sym("...")) + V("FuncDef") + V("Table") + V("SuffixedExpr"), ["FuncCall"] = Cmt(V("SuffixedExpr"), function(s, i, exp)
|
||||||
return exp["tag"] == "Call" or exp["tag"] == "Invoke", exp
|
return exp["tag"] == "Call" or exp["tag"] == "Invoke", exp
|
||||||
end), ["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp)
|
end), ["VarExpr"] = Cmt(V("SuffixedExpr"), function(s, i, exp)
|
||||||
return exp["tag"] == "Id" or exp["tag"] == "Index", exp
|
return exp["tag"] == "Id" or exp["tag"] == "Index", exp
|
||||||
|
|
@ -1807,7 +1906,7 @@ return parser
|
||||||
end
|
end
|
||||||
local parser = _() or parser
|
local parser = _() or parser
|
||||||
package["loaded"]["lib.lua-parser.parser"] = parser or true
|
package["loaded"]["lib.lua-parser.parser"] = parser or true
|
||||||
local candran = { ["VERSION"] = "0.3.1" }
|
local candran = { ["VERSION"] = "0.4.0" }
|
||||||
local default = {
|
local default = {
|
||||||
["target"] = "lua53", ["indentation"] = "", ["newline"] = "\
|
["target"] = "lua53", ["indentation"] = "", ["newline"] = "\
|
||||||
", ["requirePrefix"] = "CANDRAN_", ["mapLines"] = true, ["chunkname"] = "nil", ["rewriteErrors"] = true
|
", ["requirePrefix"] = "CANDRAN_", ["mapLines"] = true, ["chunkname"] = "nil", ["rewriteErrors"] = true
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
return function(code, ast, options)
|
return function(code, ast, options)
|
||||||
local lastInputPos = 1
|
--- Line mapping
|
||||||
local prevLinePos = 1
|
local lastInputPos = 1 -- last token position in the input code
|
||||||
local lastSource = "nil"
|
local prevLinePos = 1 -- last token position in the previous line of code in the input code
|
||||||
local lastLine = 1
|
local lastSource = "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
|
local indentLevel = 0
|
||||||
|
-- Returns a newline.
|
||||||
local function 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
|
if options.mapLines then
|
||||||
|
|
@ -26,44 +29,83 @@ return function(code, ast, options)
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
-- Returns a newline and add one level of indentation.
|
||||||
local function indent()
|
local function indent()
|
||||||
indentLevel += 1
|
indentLevel += 1
|
||||||
return newline()
|
return newline()
|
||||||
end
|
end
|
||||||
|
-- Returns a newline and remove one level of indentation.
|
||||||
local function unindent()
|
local function unindent()
|
||||||
indentLevel -= 1
|
indentLevel -= 1
|
||||||
return newline()
|
return newline()
|
||||||
end
|
end
|
||||||
|
|
||||||
local required = {}
|
--- Module management
|
||||||
|
local required = {} -- { ["module"] = true, ... }
|
||||||
local requireStr = ""
|
local requireStr = ""
|
||||||
local function addRequire(str, name, field)
|
-- 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".
|
||||||
if not required[str] then
|
local function addRequire(mod, name, field)
|
||||||
requireStr ..= "local " .. options.requirePrefix .. name .. (" = require(%q)"):format(str) .. (field and "."..field or "") .. options.newline
|
if not required[mod] then
|
||||||
required[str] = true
|
requireStr ..= "local " .. options.requirePrefix .. name .. (" = require(%q)"):format(mod) .. (field and "."..field or "") .. options.newline
|
||||||
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Returns the required module variable name.
|
||||||
local function getRequire(name)
|
local function getRequire(name)
|
||||||
return options.requirePrefix .. name
|
return options.requirePrefix .. name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- AST traversal helpers
|
||||||
|
-- Returns the first node from the list "list" which tag is in the list "tags", or nil if there were none.
|
||||||
|
local function any(list, tags)
|
||||||
|
local tagsCheck = {}
|
||||||
|
for _, tag in ipairs(tags) do
|
||||||
|
tagsCheck[tag] = true
|
||||||
|
end
|
||||||
|
for _, node in ipairs(list) do
|
||||||
|
if tagsCheck[node.tag] then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Modification helpers
|
||||||
|
local namedNodes = {} -- { ["name"] = ast, ... }
|
||||||
|
-- Wrap the compiled code of a named node with suffix and prefix.
|
||||||
|
local function wrap(name, prefix, suffix)
|
||||||
|
local node = namedNodes[name]
|
||||||
|
if not node then error("not inside a " .. name) end
|
||||||
|
node.prefix, node.suffix = prefix .. newline(), newline() .. suffix
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Lua compiler
|
||||||
local tags
|
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, ...)
|
local function lua(ast, forceTag, ...)
|
||||||
if options.mapLines and ast.pos then
|
if options.mapLines and ast.pos then
|
||||||
lastInputPos = ast.pos
|
lastInputPos = ast.pos
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast.tag](ast, ...)
|
return tags[forceTag or ast.tag](ast, ...)
|
||||||
end
|
end
|
||||||
|
-- Same as lua(), but gives the AST node a name which can be used for further access & modification.
|
||||||
|
local function namedLua(name, ast, ...)
|
||||||
|
local old = namedNodes[name]
|
||||||
|
namedNodes[name] = ast
|
||||||
|
local code = lua(ast, ...)
|
||||||
|
namedNodes[name] = old
|
||||||
|
return (ast.prefix or "") .. code .. (ast.suffix or "")
|
||||||
|
end
|
||||||
|
-- Tag constructors
|
||||||
tags = setmetatable({
|
tags = setmetatable({
|
||||||
-- block: { stat* } --
|
-- block: { stat* } --
|
||||||
Block = function(t)
|
Block = (t)
|
||||||
local r = ""
|
local r = ""
|
||||||
for i=1, #t-1, 1 do
|
for i=1, #t-1, 1 do
|
||||||
r = r .. lua(t[i]) .. newline()
|
r ..= lua(t[i]) .. newline()
|
||||||
end
|
end
|
||||||
if t[#t] then
|
if t[#t] then
|
||||||
r = r .. lua(t[#t])
|
r ..= lua(t[#t])
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -71,11 +113,11 @@ return function(code, ast, options)
|
||||||
-- stat --
|
-- stat --
|
||||||
|
|
||||||
-- Do{ stat* }
|
-- Do{ stat* }
|
||||||
Do = function(t)
|
Do = (t)
|
||||||
return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end"
|
return "do" .. indent() .. lua(t, "Block") .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
-- Set{ {lhs+} (opid? = opid?)? {expr+} }
|
-- Set{ {lhs+} (opid? = opid?)? {expr+} }
|
||||||
Set = function(t)
|
Set = (t)
|
||||||
if #t == 2 then
|
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
|
elseif #t == 3 then
|
||||||
|
|
@ -84,82 +126,100 @@ return function(code, ast, options)
|
||||||
if t[3] == "=" then
|
if t[3] == "=" then
|
||||||
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], t[4][1] }, "Op")
|
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], t[4][1] }, "Op")
|
||||||
for i=2, math.min(#t[4], #t[1]), 1 do
|
for i=2, math.min(#t[4], #t[1]), 1 do
|
||||||
r = r .. ", " .. lua({ t[2], t[1][i], t[4][i] }, "Op")
|
r ..= ", " .. lua({ t[2], t[1][i], t[4][i] }, "Op")
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
else
|
else
|
||||||
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[3], t[4][1], t[1][1] }, "Op")
|
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[3], t[4][1], t[1][1] }, "Op")
|
||||||
for i=2, math.min(#t[4], #t[1]), 1 do
|
for i=2, math.min(#t[4], #t[1]), 1 do
|
||||||
r = r .. ", " .. lua({ t[3], t[4][i], t[1][i] }, "Op")
|
r ..= ", " .. lua({ t[3], t[4][i], t[1][i] }, "Op")
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
else -- You are mad.
|
else -- You are mad.
|
||||||
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], { tag = "Op", t[4], t[5][1], t[1][1] } }, "Op")
|
local r = lua(t[1], "_lhs") .. " = " .. lua({ t[2], t[1][1], { tag = "Op", t[4], t[5][1], t[1][1] } }, "Op")
|
||||||
for i=2, math.min(#t[5], #t[1]), 1 do
|
for i=2, math.min(#t[5], #t[1]), 1 do
|
||||||
r = r .. ", " .. lua({ t[2], t[1][i], { tag = "Op", t[4], t[5][i], t[1][i] } }, "Op")
|
r ..= ", " .. lua({ t[2], t[1][i], { tag = "Op", t[4], t[5][i], t[1][i] } }, "Op")
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- While{ expr block }
|
-- While{ expr block }
|
||||||
While = function(t)
|
While = (t)
|
||||||
return "while " .. lua(t[1]) .. " do" .. indent() .. lua(t[2]) .. unindent() .. "end"
|
return "while " .. lua(t[1]) .. " do" .. indent() .. namedLua("loop", t[2]) .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
-- Repeat{ block expr }
|
-- Repeat{ block expr }
|
||||||
Repeat = function(t)
|
Repeat = (t)
|
||||||
return "repeat".. indent() .. lua(t[1]) .. unindent() .. "until " .. lua(t[2])
|
return "repeat".. indent() .. namedLua("loop", t[1]) .. unindent() .. "until " .. lua(t[2])
|
||||||
end,
|
end,
|
||||||
-- If{ (expr block)+ block? }
|
-- If{ (expr block)+ block? }
|
||||||
If = function(t)
|
If = (t)
|
||||||
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
local r = "if " .. lua(t[1]) .. " then" .. indent() .. lua(t[2]) .. unindent()
|
||||||
for i=3, #t-1, 2 do
|
for i=3, #t-1, 2 do
|
||||||
r = r .. "elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i+1]) .. unindent()
|
r ..= "elseif " .. lua(t[i]) .. " then" .. indent() .. lua(t[i+1]) .. unindent()
|
||||||
end
|
end
|
||||||
if #t % 2 == 1 then
|
if #t % 2 == 1 then
|
||||||
r = r .. "else" .. indent() .. lua(t[#t]) .. unindent()
|
r ..= "else" .. indent() .. lua(t[#t]) .. unindent()
|
||||||
end
|
end
|
||||||
return r .. "end"
|
return r .. "end"
|
||||||
end,
|
end,
|
||||||
-- Fornum{ ident expr expr expr? block }
|
-- Fornum{ ident expr expr expr? block }
|
||||||
Fornum = function(t)
|
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
|
if #t == 5 then
|
||||||
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
return r .. ", " .. lua(t[4]) .. " do" .. indent() .. lua(t[5]) .. unindent() .. "end"
|
||||||
else
|
else
|
||||||
return r .. " do" .. indent() .. lua(t[4]) .. unindent() .. "end"
|
return r .. " do" .. indent() .. namedLua("loop", t[4]) .. unindent() .. "end"
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- Forin{ {ident+} {expr+} block }
|
-- Forin{ {ident+} {expr+} block }
|
||||||
Forin = function(t)
|
Forin = (t)
|
||||||
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. lua(t[3]) .. unindent() .. "end"
|
return "for " .. lua(t[1], "_lhs") .. " in " .. lua(t[2], "_lhs") .. " do" .. indent() .. namedLua("loop", t[3]) .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
-- Local{ {ident+} {expr+}? }
|
-- Local{ {ident+} {expr+}? }
|
||||||
Local = function(t)
|
Local = (t)
|
||||||
local r = "local "..lua(t[1], "_lhs")
|
local r = "local "..lua(t[1], "_lhs")
|
||||||
if t[2][1] then
|
if t[2][1] then
|
||||||
r = r .. " = "..lua(t[2], "_lhs")
|
r ..= " = "..lua(t[2], "_lhs")
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end,
|
||||||
|
-- Let{ {ident+} {expr+}? }
|
||||||
|
Let = (t)
|
||||||
|
local nameList = lua(t[1], "_lhs")
|
||||||
|
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")
|
||||||
|
else
|
||||||
|
r ..= " = " .. lua(t[2], "_lhs")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
-- Localrec{ ident expr }
|
-- Localrec{ ident expr }
|
||||||
Localrec = function(t)
|
Localrec = (t)
|
||||||
return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword")
|
return "local function "..lua(t[1][1])..lua(t[2][1], "_functionWithoutKeyword")
|
||||||
end,
|
end,
|
||||||
-- Goto{ <string> }
|
-- Goto{ <string> }
|
||||||
Goto = function(t)
|
Goto = (t)
|
||||||
return "goto " .. lua(t[1], "Id")
|
return "goto " .. lua(t[1], "Id")
|
||||||
end,
|
end,
|
||||||
-- Label{ <string> }
|
-- Label{ <string> }
|
||||||
Label = function(t)
|
Label = (t)
|
||||||
return "::" .. lua(t[1], "Id") .. "::"
|
return "::" .. lua(t[1], "Id") .. "::"
|
||||||
end,
|
end,
|
||||||
-- Return{ <expr*> }
|
-- Return{ <expr*> }
|
||||||
Return = function(t)
|
Return = (t)
|
||||||
return "return "..lua(t, "_lhs")
|
return "return "..lua(t, "_lhs")
|
||||||
end,
|
end,
|
||||||
-- Break
|
-- Break
|
||||||
Break = function()
|
Break = ()
|
||||||
|
return "break"
|
||||||
|
end,
|
||||||
|
-- Continue
|
||||||
|
Continue = ()
|
||||||
|
wrap("loop", "repeat", "until true")
|
||||||
return "break"
|
return "break"
|
||||||
end,
|
end,
|
||||||
-- apply (below)
|
-- apply (below)
|
||||||
|
|
@ -167,27 +227,27 @@ return function(code, ast, options)
|
||||||
-- expr --
|
-- expr --
|
||||||
|
|
||||||
-- Nil
|
-- Nil
|
||||||
Nil = function()
|
Nil = ()
|
||||||
return "nil"
|
return "nil"
|
||||||
end,
|
end,
|
||||||
-- Dots
|
-- Dots
|
||||||
Dots = function()
|
Dots = ()
|
||||||
return "..."
|
return "..."
|
||||||
end,
|
end,
|
||||||
-- Boolean{ <boolean> }
|
-- Boolean{ <boolean> }
|
||||||
Boolean = function(t)
|
Boolean = (t)
|
||||||
return tostring(t[1])
|
return tostring(t[1])
|
||||||
end,
|
end,
|
||||||
-- Number{ <number> }
|
-- Number{ <number> }
|
||||||
Number = function(t)
|
Number = (t)
|
||||||
return tostring(t[1])
|
return tostring(t[1])
|
||||||
end,
|
end,
|
||||||
-- String{ <string> }
|
-- String{ <string> }
|
||||||
String = function(t)
|
String = (t)
|
||||||
return ("%q"):format(t[1])
|
return ("%q"):format(t[1])
|
||||||
end,
|
end,
|
||||||
-- Function{ { ( `ParPair{ Id expr } | `Id{ <string> } )* `Dots? } block }
|
-- Function{ { ( `ParPair{ Id expr } | `Id{ <string> } )* `Dots? } block }
|
||||||
_functionWithoutKeyword = function(t)
|
_functionWithoutKeyword = (t)
|
||||||
local r = "("
|
local r = "("
|
||||||
local decl = {}
|
local decl = {}
|
||||||
if t[1][1] then
|
if t[1][1] then
|
||||||
|
|
@ -196,9 +256,9 @@ return function(code, ast, options)
|
||||||
indentLevel += 1
|
indentLevel += 1
|
||||||
table.insert(decl, id .. " = " .. id .. " == nil and " .. lua(t[1][1][2]) .. " or " .. id)
|
table.insert(decl, id .. " = " .. id .. " == nil and " .. lua(t[1][1][2]) .. " or " .. id)
|
||||||
indentLevel -= 1
|
indentLevel -= 1
|
||||||
r = r .. id
|
r ..= id
|
||||||
else
|
else
|
||||||
r = r .. lua(t[1][1])
|
r ..= lua(t[1][1])
|
||||||
end
|
end
|
||||||
for i=2, #t[1], 1 do
|
for i=2, #t[1], 1 do
|
||||||
if t[1][i].tag == "ParPair" then
|
if t[1][i].tag == "ParPair" then
|
||||||
|
|
@ -206,26 +266,26 @@ return function(code, ast, options)
|
||||||
indentLevel += 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
|
indentLevel -= 1
|
||||||
r = r .. ", " ..id
|
r ..= ", " ..id
|
||||||
else
|
else
|
||||||
r = r .. ", " .. lua(t[1][i])
|
r ..= ", " .. lua(t[1][i])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
r = r .. ")" .. indent()
|
r ..= ")" .. indent()
|
||||||
for _, d in ipairs(decl) do
|
for _, d in ipairs(decl) do
|
||||||
r = r .. d .. newline()
|
r ..= d .. newline()
|
||||||
end
|
end
|
||||||
return r .. lua(t[2]) .. unindent() .. "end"
|
return r .. lua(t[2]) .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
Function = function(t)
|
Function = (t)
|
||||||
return "function" .. lua(t, "_functionWithoutKeyword")
|
return "function" .. lua(t, "_functionWithoutKeyword")
|
||||||
end,
|
end,
|
||||||
-- Table{ ( `Pair{ expr expr } | expr )* }
|
-- Table{ ( `Pair{ expr expr } | expr )* }
|
||||||
Pair = function(t)
|
Pair = (t)
|
||||||
return "[" .. lua(t[1]) .. "] = " .. lua(t[2])
|
return "[" .. lua(t[1]) .. "] = " .. lua(t[2])
|
||||||
end,
|
end,
|
||||||
Table = function(t)
|
Table = (t)
|
||||||
if #t == 0 then
|
if #t == 0 then
|
||||||
return "{}"
|
return "{}"
|
||||||
elseif #t == 1 then
|
elseif #t == 1 then
|
||||||
|
|
@ -235,7 +295,7 @@ return function(code, ast, options)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- Op{ opid expr expr? }
|
-- Op{ opid expr expr? }
|
||||||
Op = function(t)
|
Op = (t)
|
||||||
local r
|
local r
|
||||||
if #t == 2 then
|
if #t == 2 then
|
||||||
if type(tags._opid[t[1]]) == "string" then
|
if type(tags._opid[t[1]]) == "string" then
|
||||||
|
|
@ -253,7 +313,7 @@ return function(code, ast, options)
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
-- Paren{ expr }
|
-- Paren{ expr }
|
||||||
Paren = function(t)
|
Paren = (t)
|
||||||
return "(" .. lua(t[1]) .. ")"
|
return "(" .. lua(t[1]) .. ")"
|
||||||
end,
|
end,
|
||||||
-- apply (below)
|
-- apply (below)
|
||||||
|
|
@ -262,23 +322,23 @@ return function(code, ast, options)
|
||||||
-- apply --
|
-- apply --
|
||||||
|
|
||||||
-- Call{ expr expr* }
|
-- Call{ expr expr* }
|
||||||
Call = function(t)
|
Call = (t)
|
||||||
return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")"
|
return lua(t[1]) .. "(" .. lua(t, "_lhs", 2) .. ")"
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Invoke{ expr `String{ <string> } expr* }
|
-- Invoke{ expr `String{ <string> } expr* }
|
||||||
Invoke = function(t)
|
Invoke = (t)
|
||||||
return lua(t[1])..":"..lua(t[2], "Id").."("..lua(t, "_lhs", 3)..")"
|
return lua(t[1])..":"..lua(t[2], "Id").."("..lua(t, "_lhs", 3)..")"
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- lhs --
|
-- lhs --
|
||||||
_lhs = function(t, start)
|
_lhs = (t, start)
|
||||||
start = start or 1
|
start = start or 1
|
||||||
local r
|
local r
|
||||||
if t[start] then
|
if t[start] then
|
||||||
r = lua(t[start])
|
r = lua(t[start])
|
||||||
for i=start+1, #t, 1 do
|
for i=start+1, #t, 1 do
|
||||||
r = r .. ", "..lua(t[i])
|
r ..= ", "..lua(t[i])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
r = ""
|
r = ""
|
||||||
|
|
@ -286,11 +346,11 @@ return function(code, ast, options)
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
-- Id{ <string> }
|
-- Id{ <string> }
|
||||||
Id = function(t)
|
Id = (t)
|
||||||
return t[1]
|
return t[1]
|
||||||
end,
|
end,
|
||||||
-- Index{ expr expr }
|
-- Index{ expr expr }
|
||||||
Index = function(t)
|
Index = (t)
|
||||||
return lua(t[1]).."["..lua(t[2]).."]"
|
return lua(t[1]).."["..lua(t[2]).."]"
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
@ -303,12 +363,13 @@ return function(code, ast, options)
|
||||||
["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not"
|
["and"] = "and", ["or"] = "or", unm = "-", len = "#", bnot = "~", ["not"] = "not"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
__index = function(self, key)
|
__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 Lua 5.3")
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
#placeholder("patch")
|
#placeholder("patch")
|
||||||
|
|
||||||
return requireStr .. lua(ast) .. newline()
|
local code = lua(ast) .. newline()
|
||||||
|
return requireStr .. code
|
||||||
end
|
end
|
||||||
|
|
|
||||||
24
ideas.txt
24
ideas.txt
|
|
@ -40,23 +40,6 @@ local a = new Thing()
|
||||||
->
|
->
|
||||||
(TODO: define how classes work. May even use ClassCommons)
|
(TODO: define how classes work. May even use ClassCommons)
|
||||||
|
|
||||||
* continue keyword for loops
|
|
||||||
while true do
|
|
||||||
stuff()
|
|
||||||
if thing then
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
->
|
|
||||||
while true do
|
|
||||||
repeat
|
|
||||||
stuff()
|
|
||||||
if thing then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
until true
|
|
||||||
end
|
|
||||||
|
|
||||||
* list comprehension
|
* list comprehension
|
||||||
local a = [x for x in pairs(stuff)]
|
local a = [x for x in pairs(stuff)]
|
||||||
local a = [x for x in pairs(stuff) if x == true]
|
local a = [x for x in pairs(stuff) if x == true]
|
||||||
|
|
@ -91,6 +74,8 @@ local a = if x == true then
|
||||||
return a
|
return a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
With implicits returns?...
|
||||||
|
|
||||||
local stuff = for ... (accumulate in a table)
|
local stuff = for ... (accumulate in a table)
|
||||||
|
|
||||||
* try / except|catch / finally / else / other keywords
|
* try / except|catch / finally / else / other keywords
|
||||||
|
|
@ -139,11 +124,6 @@ local x, y $= pos
|
||||||
And in implicit assignments:
|
And in implicit assignments:
|
||||||
for i, {x, y} in ipairs(positions) do
|
for i, {x, y} in ipairs(positions) do
|
||||||
|
|
||||||
* local short alias
|
|
||||||
let a -> local a
|
|
||||||
or
|
|
||||||
var a
|
|
||||||
|
|
||||||
* Other potential inspiration
|
* Other potential inspiration
|
||||||
https://love2d.org/forums/viewtopic.php?f=3&t=82650&sid=b6d9a8dec64afcc1c67806cb5ba65458
|
https://love2d.org/forums/viewtopic.php?f=3&t=82650&sid=b6d9a8dec64afcc1c67806cb5ba65458
|
||||||
https://www.ruby-lang.org/fr/
|
https://www.ruby-lang.org/fr/
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,13 @@ stat:
|
||||||
| `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b 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
|
| `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end
|
||||||
| `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2...
|
| `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2...
|
||||||
|
| `Let{ {ident+} {expr+}? } -- let i1, i2... = e1, e2...
|
||||||
| `Localrec{ ident expr } -- only used for 'local function'
|
| `Localrec{ ident expr } -- only used for 'local function'
|
||||||
| `Goto{ <string> } -- goto str
|
| `Goto{ <string> } -- goto str
|
||||||
| `Label{ <string> } -- ::str::
|
| `Label{ <string> } -- ::str::
|
||||||
| `Return{ <expr*> } -- return e1, e2...
|
| `Return{ <expr*> } -- return e1, e2...
|
||||||
| `Break -- break
|
| `Break -- break
|
||||||
|
| `Continue -- continue
|
||||||
| apply
|
| apply
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
|
|
@ -93,6 +95,7 @@ local labels = {
|
||||||
{ "ErrDoFor", "expected 'do' after the range of the for loop" },
|
{ "ErrDoFor", "expected 'do' after the range of the for loop" },
|
||||||
|
|
||||||
{ "ErrDefLocal", "expected a function definition or assignment after local" },
|
{ "ErrDefLocal", "expected a function definition or assignment after local" },
|
||||||
|
{ "ErrDefLet", "expected a function definition or assignment after let" },
|
||||||
{ "ErrNameLFunc", "expected a function name after 'function'" },
|
{ "ErrNameLFunc", "expected a function name after 'function'" },
|
||||||
{ "ErrEListLAssign", "expected one or more expressions after '='" },
|
{ "ErrEListLAssign", "expected one or more expressions after '='" },
|
||||||
{ "ErrEListAssign", "expected one or more expressions after '='" },
|
{ "ErrEListAssign", "expected one or more expressions after '='" },
|
||||||
|
|
@ -272,7 +275,7 @@ local G = { V"Lua",
|
||||||
|
|
||||||
Block = tagC("Block", V"Stat"^0 * V"RetStat"^-1);
|
Block = tagC("Block", V"Stat"^0 * V"RetStat"^-1);
|
||||||
Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat"
|
Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat"
|
||||||
+ V"LocalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat"
|
+ V"LocalStat" + V"LetStat" + V"FuncStat" + V"BreakStat" + V"ContinueStat" + V"LabelStat" + V"GoToStat"
|
||||||
+ V"FuncCall" + V"Assignment" + sym(";") + -V"BlockEnd" * throw("InvalidStat");
|
+ V"FuncCall" + V"Assignment" + sym(";") + -V"BlockEnd" * throw("InvalidStat");
|
||||||
BlockEnd = P"return" + "end" + "elseif" + "else" + "until" + -1;
|
BlockEnd = P"return" + "end" + "elseif" + "else" + "until" + -1;
|
||||||
|
|
||||||
|
|
@ -296,6 +299,10 @@ local G = { V"Lua",
|
||||||
LocalStat = kw("local") * expect(V"LocalFunc" + V"LocalAssign", "DefLocal");
|
LocalStat = kw("local") * expect(V"LocalFunc" + V"LocalAssign", "DefLocal");
|
||||||
LocalFunc = tagC("Localrec", kw("function") * expect(V"Id", "NameLFunc") * V"FuncBody") / fixFuncStat;
|
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())));
|
||||||
|
|
||||||
|
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 * (sym("=") / "=") * V"BinOp"^-1 * expect(V"ExprList", "EListAssign"));
|
Assignment = tagC("Set", V"VarList" * V"BinOp"^-1 * (sym("=") / "=") * V"BinOp"^-1 * expect(V"ExprList", "EListAssign"));
|
||||||
|
|
||||||
FuncStat = tagC("Set", kw("function") * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat;
|
FuncStat = tagC("Set", kw("function") * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat;
|
||||||
|
|
@ -312,10 +319,11 @@ local G = { V"Lua",
|
||||||
+ V"Id";
|
+ V"Id";
|
||||||
ParKey = V"Id" * #("=" * -P"=");
|
ParKey = V"Id" * #("=" * -P"=");
|
||||||
|
|
||||||
LabelStat = tagC("Label", sym("::") * expect(V"Name", "Label") * expect(sym("::"), "CloseLabel"));
|
LabelStat = tagC("Label", sym("::") * expect(V"Name", "Label") * expect(sym("::"), "CloseLabel"));
|
||||||
GoToStat = tagC("Goto", kw("goto") * expect(V"Name", "Goto"));
|
GoToStat = tagC("Goto", kw("goto") * expect(V"Name", "Goto"));
|
||||||
BreakStat = tagC("Break", kw("break"));
|
BreakStat = tagC("Break", kw("break"));
|
||||||
RetStat = tagC("Return", kw("return") * commaSep(V"Expr", "RetList")^-1 * sym(";")^-1);
|
ContinueStat = tagC("Continue", kw("continue"));
|
||||||
|
RetStat = tagC("Return", kw("return") * commaSep(V"Expr", "RetList")^-1 * sym(";")^-1);
|
||||||
|
|
||||||
NameList = tagC("NameList", commaSep(V"Id"));
|
NameList = tagC("NameList", commaSep(V"Id"));
|
||||||
VarList = tagC("VarList", commaSep(V"VarExpr", "VarList"));
|
VarList = tagC("VarList", commaSep(V"VarExpr", "VarList"));
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,14 @@ local function traverse_break (env, stm)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function traverse_continue (env, stm)
|
||||||
|
if not insideloop(env) then
|
||||||
|
local msg = "<continue> not inside a loop"
|
||||||
|
return nil, syntaxerror(env.errorinfo, stm.pos, msg)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local function traverse_forin (env, stm)
|
local function traverse_forin (env, stm)
|
||||||
begin_loop(env)
|
begin_loop(env)
|
||||||
new_scope(env)
|
new_scope(env)
|
||||||
|
|
@ -344,7 +352,8 @@ function traverse_stm (env, stm)
|
||||||
return traverse_fornum(env, stm)
|
return traverse_fornum(env, stm)
|
||||||
elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block }
|
elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block }
|
||||||
return traverse_forin(env, stm)
|
return traverse_forin(env, stm)
|
||||||
elseif tag == "Local" then -- `Local{ {ident+} {expr+}? }
|
elseif tag == "Local" or -- `Local{ {ident+} {expr+}? }
|
||||||
|
tag == "Let" then -- `Let{ {ident+} {expr+}? }
|
||||||
return traverse_let(env, stm)
|
return traverse_let(env, stm)
|
||||||
elseif tag == "Localrec" then -- `Localrec{ ident expr }
|
elseif tag == "Localrec" then -- `Localrec{ ident expr }
|
||||||
return traverse_letrec(env, stm)
|
return traverse_letrec(env, stm)
|
||||||
|
|
@ -356,6 +365,8 @@ function traverse_stm (env, stm)
|
||||||
return traverse_return(env, stm)
|
return traverse_return(env, stm)
|
||||||
elseif tag == "Break" then
|
elseif tag == "Break" then
|
||||||
return traverse_break(env, stm)
|
return traverse_break(env, stm)
|
||||||
|
elseif tag == "Continue" then
|
||||||
|
return traverse_continue(env, stm)
|
||||||
elseif tag == "Call" then -- `Call{ expr expr* }
|
elseif tag == "Call" then -- `Call{ expr expr* }
|
||||||
return traverse_call(env, stm)
|
return traverse_call(env, stm)
|
||||||
elseif tag == "Invoke" then -- `Invoke{ expr `String{ <string> } expr* }
|
elseif tag == "Invoke" then -- `Invoke{ expr `String{ <string> } expr* }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package = "Candran"
|
package = "candran"
|
||||||
|
|
||||||
version = "0.3.1-1"
|
version = "0.4.0-1"
|
||||||
|
|
||||||
description = {
|
description = {
|
||||||
summary = "A simple Lua dialect and preprocessor.",
|
summary = "A simple Lua dialect and preprocessor.",
|
||||||
|
|
@ -9,15 +9,15 @@ description = {
|
||||||
Unlike Moonscript, Candran tries to stay close to the Lua syntax.
|
Unlike Moonscript, Candran tries to stay close to the Lua syntax.
|
||||||
]],
|
]],
|
||||||
license = "MIT",
|
license = "MIT",
|
||||||
homepage = "https://github.com/Reuh/Candran",
|
homepage = "https://github.com/Reuh/candran",
|
||||||
--issues_url = "https://github.com/Reuh/Candran", -- LuaRocks 3.0
|
--issues_url = "https://github.com/Reuh/candran", -- LuaRocks 3.0
|
||||||
maintainer = "Étienne 'Reuh' Fildadut <fildadut@reuh.eu>",
|
maintainer = "Étienne 'Reuh' Fildadut <fildadut@reuh.eu>",
|
||||||
--labels = {} -- LuaRocks 3.0
|
--labels = {} -- LuaRocks 3.0
|
||||||
}
|
}
|
||||||
|
|
||||||
source = {
|
source = {
|
||||||
url = "git://github.com/Reuh/Candran",
|
url = "git://github.com/Reuh/candran",
|
||||||
tag = "v0.3.1"
|
tag = "v0.4.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies = {
|
dependencies = {
|
||||||
36
rockspec/candran-scm-1.rockspec
Normal file
36
rockspec/candran-scm-1.rockspec
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package = "candran"
|
||||||
|
|
||||||
|
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 a preprocessor and several useful syntax additions.
|
||||||
|
Unlike Moonscript, Candran tries to stay close to the Lua syntax.
|
||||||
|
]],
|
||||||
|
license = "MIT",
|
||||||
|
homepage = "https://github.com/Reuh/candran",
|
||||||
|
--issues_url = "https://github.com/Reuh/candran", -- LuaRocks 3.0
|
||||||
|
maintainer = "Étienne 'Reuh' Fildadut <fildadut@reuh.eu>",
|
||||||
|
--labels = {} -- LuaRocks 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
source = {
|
||||||
|
url = "git://github.com/Reuh/candran"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies = {
|
||||||
|
"lua >= 5.1",
|
||||||
|
"lpeglabel >= 1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
build = {
|
||||||
|
type = "builtin",
|
||||||
|
modules = {
|
||||||
|
candran = "candran.lua"
|
||||||
|
},
|
||||||
|
install = {
|
||||||
|
bin = { "bin/can", "bin/canc" }
|
||||||
|
}
|
||||||
|
--copy_directories = { "doc", "test" }
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue