1
0
Fork 0
mirror of https://github.com/Reuh/candran.git synced 2025-10-27 17:59:30 +00:00

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
This commit is contained in:
Étienne Fildadut 2019-08-23 19:50:49 +02:00
parent ea7720b7c3
commit 91948109ca
8 changed files with 1883 additions and 1093 deletions

View file

@ -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).

View file

@ -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.

File diff suppressed because it is too large Load diff

26
compiler/lua51.can Normal file
View file

@ -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

View file

@ -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)

View file

@ -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 })

View file

@ -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 = {

View file

@ -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", [[