mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 17:59:30 +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
184
README.md
184
README.md
|
|
@ -1,27 +1,31 @@
|
||||||
Candran
|
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 a preprocessor and several useful syntax additions.
|
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.
|
||||||
|
|
||||||
Unlike Moonscript, Candran tries to stay close to the Lua syntax.
|
Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified.
|
||||||
|
|
||||||
````lua
|
````lua
|
||||||
#import("lib.thing")
|
#import("lib.thing") -- static import
|
||||||
#local debug or= false
|
#local debug or= false
|
||||||
|
|
||||||
local function calculate(toadd=25)
|
local function calculate(toadd=25) -- default parameters
|
||||||
local result = thing.do()
|
local result = thing.do()
|
||||||
result += toadd
|
result += toadd
|
||||||
#if debug then
|
#if debug then -- preprocessor conditionals
|
||||||
print("Did something")
|
print("Did something")
|
||||||
#end
|
#end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
local a = {
|
let a = {
|
||||||
hey = true,
|
hey = true,
|
||||||
|
|
||||||
newHop = :(foo, thing)
|
newHop = :(foo, thing) -- short function declaration, with self
|
||||||
@hey = thing(foo)
|
@hey = thing(foo) -- @ as an alias for self
|
||||||
|
end,
|
||||||
|
|
||||||
|
selfReference = () -- short function declaration, without self
|
||||||
|
return a -- no need for a prior local declaration using let
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,47 +33,36 @@ a:newHop(42, (foo)
|
||||||
return "something " .. foo
|
return "something " .. foo
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local list = [ -- table comprehension (kind of)
|
||||||
|
for i=1, 10 do
|
||||||
|
if i%2 == 0 then
|
||||||
|
continue -- continue keyword
|
||||||
|
end
|
||||||
|
i
|
||||||
|
end
|
||||||
|
]
|
||||||
|
|
||||||
|
local a = if condition then "one" else "two" end -- statement as expressions
|
||||||
|
|
||||||
````
|
````
|
||||||
|
|
||||||
Candran is released under the MIT License (see ```LICENSE``` for details).
|
Candran is released under the MIT License (see ```LICENSE``` for details).
|
||||||
|
|
||||||
#### Quick setup
|
#### Quick setup
|
||||||
Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.4.0-1.rockspec```.
|
Install Candran automatically using LuaRocks: ```sudo luarocks install rockspec/candran-0.5.0-1.rockspec```.
|
||||||
|
|
||||||
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```.
|
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```.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
#### Editor support
|
#### 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:
|
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:
|
||||||
* **Atom**: [language-candran](https://atom.io/packages/language-candran) support the full Candran syntax
|
* **Atom**: [language-candran](https://atom.io/packages/language-candran) support the full Candran syntax
|
||||||
|
|
||||||
The language
|
The language
|
||||||
------------
|
------------
|
||||||
### Preprocessor
|
|
||||||
Before compiling, Candran's preprocessor is run. It execute every line starting with a _#_ (ignoring whitespace) as Candran code.
|
|
||||||
For example,
|
|
||||||
|
|
||||||
````lua
|
|
||||||
#if lang == "fr" then
|
|
||||||
print("Bonjour")
|
|
||||||
#else
|
|
||||||
print("Hello")
|
|
||||||
#end
|
|
||||||
````
|
|
||||||
|
|
||||||
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.
|
|
||||||
* and every standard Lua library.
|
|
||||||
|
|
||||||
### Syntax additions
|
### Syntax additions
|
||||||
After the preprocessor is run the Candran code is compiled to Lua. The Candran code adds the folowing syntax to Lua :
|
After the preprocessor is run the Candran code is compiled to Lua. Candran code adds the folowing syntax to Lua:
|
||||||
|
|
||||||
##### Assignment operators
|
##### Assignment operators
|
||||||
* ````var += nb````
|
* ````var += nb````
|
||||||
|
|
@ -105,7 +98,7 @@ It is equivalent to doing ```if arg == nil then arg = default end``` for each ar
|
||||||
|
|
||||||
The default values can be complete Lua expressions, and will be evaluated each time the function is run.
|
The default values can be complete Lua expressions, and will be evaluated each time the function is run.
|
||||||
|
|
||||||
##### @ self aliases
|
##### `@` self aliases
|
||||||
```lua
|
```lua
|
||||||
a = {
|
a = {
|
||||||
foo = "Hoi"
|
foo = "Hoi"
|
||||||
|
|
@ -135,7 +128,7 @@ Anonymous function (functions values) can be created in a more concise way by om
|
||||||
|
|
||||||
A ```:``` can prefix the parameters paranthesis to automatically add a ```self``` parameter.
|
A ```:``` can prefix the parameters paranthesis to automatically add a ```self``` parameter.
|
||||||
|
|
||||||
##### let variable declaration
|
##### `let` variable declaration
|
||||||
```lua
|
```lua
|
||||||
let a = {
|
let a = {
|
||||||
foo = function()
|
foo = function()
|
||||||
|
|
@ -148,7 +141,7 @@ Similar to ```local```, but the variable will be declared *before* the assignemn
|
||||||
|
|
||||||
Can also be used as a shorter name for ```local```.
|
Can also be used as a shorter name for ```local```.
|
||||||
|
|
||||||
##### continue keyword
|
##### `continue` keyword
|
||||||
```lua
|
```lua
|
||||||
for i=1, 10 do
|
for i=1, 10 do
|
||||||
if i % 2 == 0 then
|
if i % 2 == 0 then
|
||||||
|
|
@ -160,16 +153,119 @@ end
|
||||||
|
|
||||||
Will skip the current loop iteration.
|
Will skip the current loop iteration.
|
||||||
|
|
||||||
|
##### `push` keyword
|
||||||
|
```lua
|
||||||
|
function a()
|
||||||
|
for i=1, 5 do
|
||||||
|
push i, "next"
|
||||||
|
end
|
||||||
|
return "done"
|
||||||
|
end
|
||||||
|
print(a()) -- 1, next, 2, next, 3, next, 4, next, 5, next, done
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
**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. Preferably use implicit `push` in these cases.
|
||||||
|
|
||||||
|
##### Implicit `push`
|
||||||
|
```lua
|
||||||
|
function a()
|
||||||
|
for i=1, 5 do
|
||||||
|
i, next
|
||||||
|
end
|
||||||
|
return "done"
|
||||||
|
end
|
||||||
|
print(a()) -- 1, next, 2, next, 3, next, 4, next, 5, next, done
|
||||||
|
|
||||||
|
-- or probably more useful...
|
||||||
|
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.
|
||||||
|
|
||||||
|
##### Statement expressions
|
||||||
|
```lua
|
||||||
|
a = if false then
|
||||||
|
"foo" -- i.e. push "foo", i.e. return "foo"
|
||||||
|
else
|
||||||
|
"bar"
|
||||||
|
end
|
||||||
|
print(a) -- bar
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
##### Table comprehension
|
||||||
|
```lua
|
||||||
|
a = [
|
||||||
|
for i=1, 10 do
|
||||||
|
i
|
||||||
|
end
|
||||||
|
] -- { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
|
||||||
|
|
||||||
|
a = [
|
||||||
|
for i=1, 10 do
|
||||||
|
if i%2 == 0 then
|
||||||
|
@[i] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
] -- { [2] = true, [4] = true, [6] = true, [8] = true, [10] = true }
|
||||||
|
|
||||||
|
a = [push unpack(t1); push unpack(t2)] -- concatenate t1 and t2
|
||||||
|
```
|
||||||
|
|
||||||
|
Comprehensions provide a shorter syntax for defining and initializing tables based on a block of code.
|
||||||
|
|
||||||
|
You can write *any* code you want between `[` and `]`, this code will be run as if it was a separate function which is immediadtly run.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Preprocessor
|
||||||
|
Before compiling, Candran's preprocessor is run. It execute every line starting with a _#_ (ignoring whitespace) as Candran code.
|
||||||
|
For example,
|
||||||
|
|
||||||
|
````lua
|
||||||
|
#if lang == "fr" then
|
||||||
|
print("Bonjour")
|
||||||
|
#else
|
||||||
|
print("Hello")
|
||||||
|
#end
|
||||||
|
````
|
||||||
|
|
||||||
|
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.
|
||||||
|
* and every standard Lua library.
|
||||||
|
|
||||||
Compile targets
|
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 both Lua 5.3 and Lua 5.1/LuaJit.
|
||||||
|
|
||||||
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``` (default) or ```luajit``` in the option table when using the library or the command line tools.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
The library
|
Usage
|
||||||
-----------
|
-----
|
||||||
### Command-line 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``` and ```can``` utility:
|
||||||
|
|
||||||
|
|
@ -197,6 +293,10 @@ The library can be used standalone through the ```canc``` and ```can``` utility:
|
||||||
|
|
||||||
preprocess and compile _foo.can_ and write the result in _foo.lua_.
|
preprocess and compile _foo.can_ and write the result in _foo.lua_.
|
||||||
|
|
||||||
|
````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.
|
preprocess _foo.can_ with _verbose_ set to _true_, compile it and execute it.
|
||||||
|
|
@ -284,7 +384,7 @@ You can give arbitrary options which will be gived to the preprocessor, but Cand
|
||||||
target = "lua53" -- Compiler target. "lua53" or "luajit".
|
target = "lua53" -- Compiler target. "lua53" or "luajit".
|
||||||
indentation = "" -- Character(s) used for indentation in the compiled file.
|
indentation = "" -- Character(s) used for indentation in the compiled file.
|
||||||
newline = "\n" -- Character(s) used for newlines in the compiled file.
|
newline = "\n" -- Character(s) used for newlines in the compiled file.
|
||||||
requirePrefix = "CANDRAN_" -- Prefix used when Candran needs to require an external library to provide some functionality (example: LuaJIT's bit lib when using bitwise operators).
|
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.
|
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.
|
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().
|
rewriteErrors = true -- True to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall().
|
||||||
|
|
@ -303,7 +403,7 @@ This command will use the precompilled version of this repository (candran.lua)
|
||||||
canc candran.can
|
canc candran.can
|
||||||
````
|
````
|
||||||
|
|
||||||
The Candran build included in this repository were made using the ```mapLines=false``` options.
|
The Candran build included in this repository was made using the ```mapLines=false``` option.
|
||||||
|
|
||||||
You can then run the tests on your build :
|
You can then run the tests on your build :
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#import("lib.lua-parser.parser")
|
#import("lib.lua-parser.parser")
|
||||||
|
|
||||||
local candran = {
|
local candran = {
|
||||||
VERSION = "0.4.0"
|
VERSION = "0.5.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Default options.
|
--- Default options.
|
||||||
|
|
@ -18,7 +18,7 @@ local default = {
|
||||||
target = "lua53",
|
target = "lua53",
|
||||||
indentation = "",
|
indentation = "",
|
||||||
newline = "\n",
|
newline = "\n",
|
||||||
requirePrefix = "CANDRAN_",
|
variablePrefix = "__CAN_",
|
||||||
mapLines = true,
|
mapLines = true,
|
||||||
chunkname = "nil",
|
chunkname = "nil",
|
||||||
rewriteErrors = true
|
rewriteErrors = true
|
||||||
|
|
|
||||||
124
candran.lua
124
candran.lua
|
|
@ -171,12 +171,12 @@ local required = {}
|
||||||
local requireStr = ""
|
local requireStr = ""
|
||||||
local function addRequire(mod, name, field)
|
local function addRequire(mod, name, field)
|
||||||
if not required[mod] then
|
if not required[mod] then
|
||||||
requireStr = requireStr .. ("local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"])
|
requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"])
|
||||||
required[mod] = true
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function getRequire(name)
|
local function var(name)
|
||||||
return options["requirePrefix"] .. name
|
return options["variablePrefix"] .. name
|
||||||
end
|
end
|
||||||
local loop = {
|
local loop = {
|
||||||
"While",
|
"While",
|
||||||
|
|
@ -238,16 +238,22 @@ lastInputPos = ast["pos"]
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast["tag"]](ast, ...)
|
return tags[forceTag or ast["tag"]](ast, ...)
|
||||||
end
|
end
|
||||||
|
local UNPACK = function(list, i, j)
|
||||||
|
return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")"
|
||||||
|
end
|
||||||
|
local APPEND = function(t, toAppend)
|
||||||
|
return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end"
|
||||||
|
end
|
||||||
tags = setmetatable({
|
tags = setmetatable({
|
||||||
["Block"] = function(t)
|
["Block"] = function(t)
|
||||||
local hasPush = not peek("push") and any(t, { "Push" }, func)
|
local hasPush = peek("push") == nil and any(t, { "Push" }, func)
|
||||||
if hasPush and hasPush == t[# t] then
|
if hasPush and hasPush == t[# t] then
|
||||||
hasPush["tag"] = "Return"
|
hasPush["tag"] = "Return"
|
||||||
hasPush = false
|
hasPush = false
|
||||||
end
|
end
|
||||||
local r = ""
|
local r = ""
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline())
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
end
|
end
|
||||||
for i = 1, # t - 1, 1 do
|
for i = 1, # t - 1, 1 do
|
||||||
r = r .. (lua(t[i]) .. newline())
|
r = r .. (lua(t[i]) .. newline())
|
||||||
|
|
@ -256,7 +262,7 @@ if t[# t] then
|
||||||
r = r .. (lua(t[# t]))
|
r = r .. (lua(t[# t]))
|
||||||
end
|
end
|
||||||
if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then
|
if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then
|
||||||
r = r .. (newline() .. "return unpack(__PUSH__)" .. pop("push"))
|
r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push"))
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -455,14 +461,25 @@ local r = ""
|
||||||
for _, val in ipairs(t) do
|
for _, val in ipairs(t) do
|
||||||
r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline())
|
r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline())
|
||||||
end
|
end
|
||||||
return r .. "return unpack(" .. push .. ")"
|
return r .. "return " .. UNPACK(push)
|
||||||
else
|
else
|
||||||
return "return " .. lua(t, "_lhs")
|
return "return " .. lua(t, "_lhs")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
["Push"] = function(t)
|
["Push"] = function(t)
|
||||||
local var = assert(peek("push"), "no context given for push")
|
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 = 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 = r .. (APPEND(var, lua(t[# t])))
|
||||||
|
else
|
||||||
|
r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r
|
||||||
end,
|
end,
|
||||||
["Break"] = function()
|
["Break"] = function()
|
||||||
return "break"
|
return "break"
|
||||||
|
|
@ -514,7 +531,21 @@ r = r .. (")" .. indent())
|
||||||
for _, d in ipairs(decl) do
|
for _, d in ipairs(decl) do
|
||||||
r = r .. (d .. newline())
|
r = r .. (d .. newline())
|
||||||
end
|
end
|
||||||
return r .. lua(t[2]) .. unindent() .. "end"
|
if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then
|
||||||
|
t[2][# t[2]]["tag"] = "Return"
|
||||||
|
end
|
||||||
|
local hasPush = any(t[2], { "Push" }, func)
|
||||||
|
if hasPush then
|
||||||
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
|
else
|
||||||
|
push("push", false)
|
||||||
|
end
|
||||||
|
r = r .. (lua(t[2]))
|
||||||
|
if hasPush then
|
||||||
|
r = r .. (newline() .. "return " .. UNPACK(var("push")))
|
||||||
|
end
|
||||||
|
pop("push")
|
||||||
|
return r .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
["Function"] = function(t)
|
["Function"] = function(t)
|
||||||
return "function" .. lua(t, "_functionWithoutKeyword")
|
return "function" .. lua(t, "_functionWithoutKeyword")
|
||||||
|
|
@ -558,12 +589,15 @@ end,
|
||||||
local hasPush = any(t, { "Push" }, func)
|
local hasPush = any(t, { "Push" }, func)
|
||||||
local r = "(function()" .. indent()
|
local r = "(function()" .. indent()
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline())
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
|
else
|
||||||
|
push("push", false)
|
||||||
end
|
end
|
||||||
r = r .. (lua(t, stat))
|
r = r .. (lua(t, stat))
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (newline() .. "return unpack(__PUSH__)" .. pop("push"))
|
r = r .. (newline() .. "return " .. UNPACK(var("push")))
|
||||||
end
|
end
|
||||||
|
pop("push")
|
||||||
r = r .. (unindent() .. "end)()")
|
r = r .. (unindent() .. "end)()")
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -696,12 +730,12 @@ local required = {}
|
||||||
local requireStr = ""
|
local requireStr = ""
|
||||||
local function addRequire(mod, name, field)
|
local function addRequire(mod, name, field)
|
||||||
if not required[mod] then
|
if not required[mod] then
|
||||||
requireStr = requireStr .. ("local " .. options["requirePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"])
|
requireStr = requireStr .. ("local " .. options["variablePrefix"] .. name .. (" = require(%q)"):format(mod) .. (field and "." .. field or "") .. options["newline"])
|
||||||
required[mod] = true
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function getRequire(name)
|
local function var(name)
|
||||||
return options["requirePrefix"] .. name
|
return options["variablePrefix"] .. name
|
||||||
end
|
end
|
||||||
local loop = {
|
local loop = {
|
||||||
"While",
|
"While",
|
||||||
|
|
@ -763,16 +797,22 @@ lastInputPos = ast["pos"]
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast["tag"]](ast, ...)
|
return tags[forceTag or ast["tag"]](ast, ...)
|
||||||
end
|
end
|
||||||
|
local UNPACK = function(list, i, j)
|
||||||
|
return "table.unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")"
|
||||||
|
end
|
||||||
|
local APPEND = function(t, toAppend)
|
||||||
|
return "do" .. indent() .. "local a = table.pack(" .. toAppend .. ")" .. newline() .. "table.move(a, 1, a.n, #" .. t .. "+1, " .. t .. ")" .. unindent() .. "end"
|
||||||
|
end
|
||||||
tags = setmetatable({
|
tags = setmetatable({
|
||||||
["Block"] = function(t)
|
["Block"] = function(t)
|
||||||
local hasPush = not peek("push") and any(t, { "Push" }, func)
|
local hasPush = peek("push") == nil and any(t, { "Push" }, func)
|
||||||
if hasPush and hasPush == t[# t] then
|
if hasPush and hasPush == t[# t] then
|
||||||
hasPush["tag"] = "Return"
|
hasPush["tag"] = "Return"
|
||||||
hasPush = false
|
hasPush = false
|
||||||
end
|
end
|
||||||
local r = ""
|
local r = ""
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline())
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
end
|
end
|
||||||
for i = 1, # t - 1, 1 do
|
for i = 1, # t - 1, 1 do
|
||||||
r = r .. (lua(t[i]) .. newline())
|
r = r .. (lua(t[i]) .. newline())
|
||||||
|
|
@ -781,7 +821,7 @@ if t[# t] then
|
||||||
r = r .. (lua(t[# t]))
|
r = r .. (lua(t[# t]))
|
||||||
end
|
end
|
||||||
if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then
|
if hasPush and (t[# t] and t[# t]["tag"] ~= "Return") then
|
||||||
r = r .. (newline() .. "return unpack(__PUSH__)" .. pop("push"))
|
r = r .. (newline() .. "return " .. UNPACK(var("push")) .. pop("push"))
|
||||||
end
|
end
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -980,14 +1020,25 @@ local r = ""
|
||||||
for _, val in ipairs(t) do
|
for _, val in ipairs(t) do
|
||||||
r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline())
|
r = r .. (push .. "[#" .. push .. "+1] = " .. lua(val) .. newline())
|
||||||
end
|
end
|
||||||
return r .. "return unpack(" .. push .. ")"
|
return r .. "return " .. UNPACK(push)
|
||||||
else
|
else
|
||||||
return "return " .. lua(t, "_lhs")
|
return "return " .. lua(t, "_lhs")
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
["Push"] = function(t)
|
["Push"] = function(t)
|
||||||
local var = assert(peek("push"), "no context given for push")
|
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 = 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 = r .. (APPEND(var, lua(t[# t])))
|
||||||
|
else
|
||||||
|
r = r .. (var .. "[#" .. var .. "+1] = " .. lua(t[# t]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r
|
||||||
end,
|
end,
|
||||||
["Break"] = function()
|
["Break"] = function()
|
||||||
return "break"
|
return "break"
|
||||||
|
|
@ -1039,7 +1090,21 @@ r = r .. (")" .. indent())
|
||||||
for _, d in ipairs(decl) do
|
for _, d in ipairs(decl) do
|
||||||
r = r .. (d .. newline())
|
r = r .. (d .. newline())
|
||||||
end
|
end
|
||||||
return r .. lua(t[2]) .. unindent() .. "end"
|
if t[2][# t[2]] and t[2][# t[2]]["tag"] == "Push" then
|
||||||
|
t[2][# t[2]]["tag"] = "Return"
|
||||||
|
end
|
||||||
|
local hasPush = any(t[2], { "Push" }, func)
|
||||||
|
if hasPush then
|
||||||
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
|
else
|
||||||
|
push("push", false)
|
||||||
|
end
|
||||||
|
r = r .. (lua(t[2]))
|
||||||
|
if hasPush then
|
||||||
|
r = r .. (newline() .. "return " .. UNPACK(var("push")))
|
||||||
|
end
|
||||||
|
pop("push")
|
||||||
|
return r .. unindent() .. "end"
|
||||||
end,
|
end,
|
||||||
["Function"] = function(t)
|
["Function"] = function(t)
|
||||||
return "function" .. lua(t, "_functionWithoutKeyword")
|
return "function" .. lua(t, "_functionWithoutKeyword")
|
||||||
|
|
@ -1083,12 +1148,15 @@ end,
|
||||||
local hasPush = any(t, { "Push" }, func)
|
local hasPush = any(t, { "Push" }, func)
|
||||||
local r = "(function()" .. indent()
|
local r = "(function()" .. indent()
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline())
|
r = r .. (push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline())
|
||||||
|
else
|
||||||
|
push("push", false)
|
||||||
end
|
end
|
||||||
r = r .. (lua(t, stat))
|
r = r .. (lua(t, stat))
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r = r .. (newline() .. "return unpack(__PUSH__)" .. pop("push"))
|
r = r .. (newline() .. "return " .. UNPACK(var("push")))
|
||||||
end
|
end
|
||||||
|
pop("push")
|
||||||
r = r .. (unindent() .. "end)()")
|
r = r .. (unindent() .. "end)()")
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -1174,6 +1242,12 @@ end,
|
||||||
}, { ["__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 })
|
||||||
|
UNPACK = function(list, i, j)
|
||||||
|
return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")"
|
||||||
|
end
|
||||||
|
APPEND = function(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"] = function(left, right)
|
tags["_opid"]["idiv"] = function(left, right)
|
||||||
return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")"
|
return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
|
|
@ -1465,7 +1539,7 @@ local status, msg = traverse_varlist(env, stm[1])
|
||||||
if not status then
|
if not status then
|
||||||
return status, msg
|
return status, msg
|
||||||
end
|
end
|
||||||
status, msg = traverse_explist(env, stm[2])
|
status, msg = traverse_explist(env, stm[# stm])
|
||||||
if not status then
|
if not status then
|
||||||
return status, msg
|
return status, msg
|
||||||
end
|
end
|
||||||
|
|
@ -2708,13 +2782,13 @@ 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.4.0" }
|
local candran = { ["VERSION"] = "0.5.0" }
|
||||||
local default = {
|
local default = {
|
||||||
["target"] = "lua53",
|
["target"] = "lua53",
|
||||||
["indentation"] = "",
|
["indentation"] = "",
|
||||||
["newline"] = "\
|
["newline"] = "\
|
||||||
",
|
",
|
||||||
["requirePrefix"] = "CANDRAN_",
|
["variablePrefix"] = "__CAN_",
|
||||||
["mapLines"] = true,
|
["mapLines"] = true,
|
||||||
["chunkname"] = "nil",
|
["chunkname"] = "nil",
|
||||||
["rewriteErrors"] = true
|
["rewriteErrors"] = true
|
||||||
|
|
|
||||||
|
|
@ -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".
|
-- 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 function addRequire(mod, name, field)
|
||||||
if not required[mod] then
|
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
|
required[mod] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Returns the required module variable name.
|
|
||||||
local function getRequire(name)
|
--- Variable management
|
||||||
return options.requirePrefix .. name
|
-- Returns the prefixed variable name.
|
||||||
|
local function var(name)
|
||||||
|
return options.variablePrefix .. name
|
||||||
end
|
end
|
||||||
|
|
||||||
--- AST traversal helpers
|
--- AST traversal helpers
|
||||||
|
|
@ -112,18 +114,27 @@ return function(code, ast, options)
|
||||||
end
|
end
|
||||||
return tags[forceTag or ast.tag](ast, ...)
|
return tags[forceTag or ast.tag](ast, ...)
|
||||||
end
|
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({
|
tags = setmetatable({
|
||||||
-- block: { stat* } --
|
-- block: { stat* } --
|
||||||
Block = (t)
|
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
|
if hasPush and hasPush == t[#t] then -- if the first push is the last statement, it's just a return
|
||||||
hasPush.tag = "Return"
|
hasPush.tag = "Return"
|
||||||
hasPush = false
|
hasPush = false
|
||||||
end
|
end
|
||||||
local r = ""
|
local r = ""
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r ..= push("push", "__PUSH__") .. "local __PUSH__ = {}" .. newline()
|
r ..= push("push", var("push")) .. "local " .. var("push") .. " = {}" .. newline()
|
||||||
end
|
end
|
||||||
for i=1, #t-1, 1 do
|
for i=1, #t-1, 1 do
|
||||||
r ..= lua(t[i]) .. newline()
|
r ..= lua(t[i]) .. newline()
|
||||||
|
|
@ -132,7 +143,7 @@ return function(code, ast, options)
|
||||||
r ..= lua(t[#t])
|
r ..= lua(t[#t])
|
||||||
end
|
end
|
||||||
if hasPush and (t[#t] and t[#t].tag ~= "Return") then -- add return only if needed
|
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
|
end
|
||||||
return r
|
return r
|
||||||
end,
|
end,
|
||||||
|
|
@ -291,7 +302,7 @@ return function(code, ast, options)
|
||||||
for _, val in ipairs(t) do
|
for _, val in ipairs(t) do
|
||||||
r ..= push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()
|
r ..= push .. "[#" .. push .. "+1] = " .. lua(val) .. newline()
|
||||||
end
|
end
|
||||||
return r .. "return unpack(" .. push .. ")"
|
return r .. "return " .. UNPACK(push)
|
||||||
else
|
else
|
||||||
return "return "..lua(t, "_lhs")
|
return "return "..lua(t, "_lhs")
|
||||||
end
|
end
|
||||||
|
|
@ -299,7 +310,18 @@ return function(code, ast, options)
|
||||||
-- Push{ <expr*> }
|
-- Push{ <expr*> }
|
||||||
Push = (t)
|
Push = (t)
|
||||||
local var = assert(peek("push"), "no context given for push")
|
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,
|
end,
|
||||||
-- Break
|
-- Break
|
||||||
Break = ()
|
Break = ()
|
||||||
|
|
@ -363,7 +385,21 @@ return function(code, ast, options)
|
||||||
for _, d in ipairs(decl) do
|
for _, d in ipairs(decl) do
|
||||||
r ..= d .. newline()
|
r ..= d .. newline()
|
||||||
end
|
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,
|
end,
|
||||||
Function = (t)
|
Function = (t)
|
||||||
return "function" .. lua(t, "_functionWithoutKeyword")
|
return "function" .. lua(t, "_functionWithoutKeyword")
|
||||||
|
|
@ -416,12 +452,15 @@ return function(code, ast, options)
|
||||||
local hasPush = any(t, { "Push" }, func)
|
local hasPush = any(t, { "Push" }, func)
|
||||||
local r = "(function()" .. indent()
|
local r = "(function()" .. indent()
|
||||||
if hasPush then
|
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
|
end
|
||||||
r ..= lua(t, stat)
|
r ..= lua(t, stat)
|
||||||
if hasPush then
|
if hasPush then
|
||||||
r ..= newline() .. "return unpack(__PUSH__)" .. pop("push")
|
r ..= newline() .. "return " .. UNPACK(var("push"))
|
||||||
end
|
end
|
||||||
|
pop("push")
|
||||||
r ..= unindent() .. "end)()"
|
r ..= unindent() .. "end)()"
|
||||||
return r
|
return r
|
||||||
end,
|
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) .. ")"
|
return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.band = function(left, right)
|
tags._opid.band = (left, right)
|
||||||
addRequire("bit", "band", "band")
|
addRequire("bit", "band", "band")
|
||||||
return getRequire("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
return getRequire("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.bor = function(left, right)
|
tags._opid.bor = (left, right)
|
||||||
addRequire("bit", "bor", "bor")
|
addRequire("bit", "bor", "bor")
|
||||||
return getRequire("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
return getRequire("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.bxor = function(left, right)
|
tags._opid.bxor = (left, right)
|
||||||
addRequire("bit", "bxor", "bxor")
|
addRequire("bit", "bxor", "bxor")
|
||||||
return getRequire("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
return getRequire("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.shl = function(left, right)
|
tags._opid.shl = (left, right)
|
||||||
addRequire("bit", "lshift", "lshift")
|
addRequire("bit", "lshift", "lshift")
|
||||||
return getRequire("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
return getRequire("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.shr = function(left, right)
|
tags._opid.shr = (left, right)
|
||||||
addRequire("bit", "rshift", "rshift")
|
addRequire("bit", "rshift", "rshift")
|
||||||
return getRequire("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
return getRequire("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
tags._opid.bnot = function(right)
|
tags._opid.bnot = (right)
|
||||||
addRequire("bit", "bnot", "bnot")
|
addRequire("bit", "bnot", "bnot")
|
||||||
return getRequire("bnot") .. "(" .. lua(right) .. ")"
|
return getRequire("bnot") .. "(" .. lua(right) .. ")"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ end
|
||||||
local function traverse_assignment (env, stm)
|
local function traverse_assignment (env, stm)
|
||||||
local status, msg = traverse_varlist(env, stm[1])
|
local status, msg = traverse_varlist(env, stm[1])
|
||||||
if not status then return status, msg end
|
if not status then return status, msg end
|
||||||
status, msg = traverse_explist(env, stm[2])
|
status, msg = traverse_explist(env, stm[#stm])
|
||||||
if not status then return status, msg end
|
if not status then return status, msg end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
@ -372,7 +372,7 @@ function traverse_stm (env, stm)
|
||||||
local tag = stm.tag
|
local tag = stm.tag
|
||||||
if tag == "Do" then -- `Do{ stat* }
|
if tag == "Do" then -- `Do{ stat* }
|
||||||
return traverse_block(env, stm)
|
return traverse_block(env, stm)
|
||||||
elseif tag == "Set" then -- `Set{ {lhs+} {expr+} }
|
elseif tag == "Set" then -- `Set{ {lhs+} (opid? = opid?)? {expr+} }
|
||||||
return traverse_assignment(env, stm)
|
return traverse_assignment(env, stm)
|
||||||
elseif tag == "While" then -- `While{ expr block }
|
elseif tag == "While" then -- `While{ expr block }
|
||||||
return traverse_while(env, stm)
|
return traverse_while(env, stm)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package = "candran"
|
package = "candran"
|
||||||
|
|
||||||
version = "0.4.0-1"
|
version = "0.5.0-1"
|
||||||
|
|
||||||
description = {
|
description = {
|
||||||
summary = "A simple Lua dialect and preprocessor.",
|
summary = "A simple Lua dialect and preprocessor.",
|
||||||
detailed = [[
|
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.
|
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.
|
Unlike Moonscript, Candran tries to stay close to the Lua syntax, and existing Lua code can run on Candran unmodified.
|
||||||
]],
|
]],
|
||||||
license = "MIT",
|
license = "MIT",
|
||||||
homepage = "https://github.com/Reuh/candran",
|
homepage = "https://github.com/Reuh/candran",
|
||||||
|
|
@ -17,7 +17,7 @@ description = {
|
||||||
|
|
||||||
source = {
|
source = {
|
||||||
url = "git://github.com/Reuh/candran",
|
url = "git://github.com/Reuh/candran",
|
||||||
tag = "v0.4.0"
|
tag = "v0.5.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies = {
|
dependencies = {
|
||||||
Loading…
Add table
Add a link
Reference in a new issue