diff --git a/candran.lua b/candran.lua index af2608b..289a23e 100644 --- a/candran.lua +++ b/candran.lua @@ -541,7 +541,7 @@ else push("push", false) end r = r .. (lua(t[2])) -if hasPush then +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then r = r .. (newline() .. "return " .. UNPACK(var("push"))) end pop("push") @@ -1100,7 +1100,7 @@ else push("push", false) end r = r .. (lua(t[2])) -if hasPush then +if hasPush and (t[2][# t[2]] and t[2][# t[2]]["tag"] ~= "Return") then r = r .. (newline() .. "return " .. UNPACK(var("push"))) end pop("push") @@ -2667,7 +2667,7 @@ V("Lua"), ["PushStat"] = tagC("Push", kw("push") * commaSep(V("Expr"), "RetList") ^ - 1 * sym(";") ^ - 1), ["ImplicitPushStat"] = tagC("Push", commaSep(V("Expr"), "RetList") * sym(";") ^ - 1), ["NameList"] = tagC("NameList", commaSep(V("Id"))), -["VarList"] = tagC("VarList", commaSep(V("VarExpr"), "VarList")), +["VarList"] = tagC("VarList", commaSep(V("VarExpr"))), ["ExprList"] = tagC("ExpList", commaSep(V("Expr"), "ExprList")), ["Expr"] = V("OrExpr"), ["OrExpr"] = chainOp(V("AndExpr"), V("OrOp"), "OrExpr"), diff --git a/compiler/lua53.can b/compiler/lua53.can index 23ddc75..776912a 100644 --- a/compiler/lua53.can +++ b/compiler/lua53.can @@ -395,7 +395,7 @@ return function(code, ast, options) push("push", false) -- no push here (make sure higher push don't affect us) end r ..= lua(t[2]) - if hasPush then + 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") diff --git a/lib/lua-parser/parser.lua b/lib/lua-parser/parser.lua index 0547209..f0c3723 100644 --- a/lib/lua-parser/parser.lua +++ b/lib/lua-parser/parser.lua @@ -349,7 +349,7 @@ local G = { V"Lua", ImplicitPushStat = tagC("Push", commaSep(V"Expr", "RetList") * sym(";")^-1); NameList = tagC("NameList", commaSep(V"Id")); - VarList = tagC("VarList", commaSep(V"VarExpr", "VarList")); + VarList = tagC("VarList", commaSep(V"VarExpr")); ExprList = tagC("ExpList", commaSep(V"Expr", "ExprList")); Expr = V"OrExpr"; diff --git a/test/test.lua b/test/test.lua index a5669bd..10c81fa 100644 --- a/test/test.lua +++ b/test/test.lua @@ -313,6 +313,99 @@ end return a ]], "13579") +-- push keyword +test("push keyword", [[ +function a() + for i=1, 5 do + push i, "next" + end + return "done" +end +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()}) +]], "5heyfoobar") + +-- implicit push +test("implicit push", [[ +function a() + for i=1, 5 do + i, "next" + end + return "done" +end +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() + 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 +]], "bar") +test("do statement expressions", [[ +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)}) +]], "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)}) +]], "12nil") +test("for statement expressions", [[ +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]) +]], "12345678910") +test("table comprehension associative/self", [[ +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)]) +]], "heyhopfoobar") + -- results local resultCounter = {} local testCounter = 0