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 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
|
||||
#import("lib.thing")
|
||||
#import("lib.thing") -- static import
|
||||
#local debug or= false
|
||||
|
||||
local function calculate(toadd=25)
|
||||
local function calculate(toadd=25) -- default parameters
|
||||
local result = thing.do()
|
||||
result += toadd
|
||||
#if debug then
|
||||
#if debug then -- preprocessor conditionals
|
||||
print("Did something")
|
||||
#end
|
||||
return result
|
||||
end
|
||||
|
||||
local a = {
|
||||
let a = {
|
||||
hey = true,
|
||||
|
||||
newHop = :(foo, thing)
|
||||
@hey = thing(foo)
|
||||
newHop = :(foo, thing) -- short function declaration, with self
|
||||
@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
|
||||
}
|
||||
|
||||
|
|
@ -29,47 +33,36 @@ a:newHop(42, (foo)
|
|||
return "something " .. foo
|
||||
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).
|
||||
|
||||
#### 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```.
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
* ````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.
|
||||
|
||||
##### @ self aliases
|
||||
##### `@` self aliases
|
||||
```lua
|
||||
a = {
|
||||
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.
|
||||
|
||||
##### let variable declaration
|
||||
##### `let` variable declaration
|
||||
```lua
|
||||
let a = {
|
||||
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```.
|
||||
|
||||
##### continue keyword
|
||||
##### `continue` keyword
|
||||
```lua
|
||||
for i=1, 10 do
|
||||
if i % 2 == 0 then
|
||||
|
|
@ -160,16 +153,119 @@ end
|
|||
|
||||
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
|
||||
---------------
|
||||
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.
|
||||
|
||||
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
|
||||
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_.
|
||||
|
||||
````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````
|
||||
|
||||
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".
|
||||
indentation = "" -- Character(s) used for indentation 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.
|
||||
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().
|
||||
|
|
@ -303,7 +403,7 @@ This command will use the precompilled version of this repository (candran.lua)
|
|||
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 :
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue