mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 17:59:30 +00:00
v0.3.1
Updated tests, added a few usefull options to #import()
This commit is contained in:
parent
83156361cd
commit
97454746b8
6 changed files with 197 additions and 53 deletions
|
|
@ -53,7 +53,7 @@ Will output ````print("Bonjour")```` or ````print("Hello")```` depending of the
|
|||
The preprocessor has access to the following variables :
|
||||
* ````candran```` : the Candran library table.
|
||||
* ````output```` : the current preprocessor output string.
|
||||
* ````import(module[, [args, autoRequire]])```` : a function which import a module. This is equivalent to use _require(module)_ in the Candran code, except the module will be embedded in the current file. _args_ is an optional preprocessor arguments table for the imported module (current preprocessor arguments will be inherited). _autoRequire_ (boolean, default true) indicate if the module should be automaticaly loaded in a local variable or not. If true, the local variable will have the name of the module.
|
||||
* ````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.
|
||||
|
|
@ -255,6 +255,8 @@ chunkname = "nil" -- The chunkname used when running code using the helper funct
|
|||
rewriteErrors = true -- True to enable error rewriting when loading code using the helper functions. Will wrap the whole code in a xpcall().
|
||||
```
|
||||
|
||||
There are also a few function-specific options available, see the associated functions documentation for more information.
|
||||
|
||||
### Compiling the library
|
||||
The Candran library itself is written is Candran, so you have to compile it with an already compiled Candran library.
|
||||
|
||||
|
|
|
|||
20
candran.can
20
candran.can
|
|
@ -10,7 +10,7 @@
|
|||
#import("lib.lua-parser.parser")
|
||||
|
||||
local candran = {
|
||||
VERSION = "0.3.0"
|
||||
VERSION = "0.3.1"
|
||||
}
|
||||
|
||||
--- Default options.
|
||||
|
|
@ -53,17 +53,19 @@ function candran.preprocess(input, options={})
|
|||
--- Current preprocessor output
|
||||
env.output = ""
|
||||
--- Import an external Candran/Lua module into the generated file
|
||||
-- Notable options:
|
||||
-- * loadLocal (true): true to automatically load the module into a local variable
|
||||
-- * loadPackage (true): true to automatically load the module into the loaded packages table
|
||||
-- @tparam modpath string module path
|
||||
-- @tparam margs table preprocessor arguments to use when preprocessessing the module
|
||||
-- @tparam autoRequire[opt=true] boolean true to automatically load the module into a local variable
|
||||
env.import = function(modpath, margs={}, autoRequire=true)
|
||||
-- @tparam margs table preprocessor options to use when preprocessessing the module
|
||||
env.import = function(modpath, margs={})
|
||||
local filepath = assert(util.search(modpath), "No module named \""..modpath.."\"")
|
||||
|
||||
-- open module file
|
||||
local f = io.open(filepath)
|
||||
if not f then error("Can't open the module file to import") end
|
||||
|
||||
margs = util.merge(options, { chunkname = filepath }, margs)
|
||||
margs = util.merge(options, { chunkname = filepath, loadLocal = true, loadPackage = true }, margs)
|
||||
local modcontent = candran.preprocess(f:read("*a"), margs)
|
||||
f:close()
|
||||
|
||||
|
|
@ -71,13 +73,13 @@ function candran.preprocess(input, options={})
|
|||
local modname = modpath:match("[^%.]+$")
|
||||
|
||||
env.write(
|
||||
"-- MODULE \""..modpath.."\" --\n"..
|
||||
"-- MODULE "..modpath.." --\n"..
|
||||
"local function _()\n"..
|
||||
modcontent.."\n"..
|
||||
"end\n"..
|
||||
(autoRequire and "local "..modname.." = _() or "..modname.."\n" or "").. -- auto require
|
||||
"package.loaded[\""..modpath.."\"] = "..(autoRequire and modname or "_()").." or true\n".. -- add to package.loaded
|
||||
"-- END OF MODULE \""..modpath.."\" --"
|
||||
(margs.loadLocal and ("local %s = _() or %s\n"):format(modname, modname) or "").. -- auto require
|
||||
(margs.loadPackage and ("package.loaded[%q] = %s or true\n"):format(modpath, margs.loadLocal and modname or "_()") or "").. -- add to package.loaded
|
||||
"-- END OF MODULE "..modpath.." --"
|
||||
)
|
||||
end
|
||||
--- Include another file content in the preprocessor output.
|
||||
|
|
|
|||
18
candran.lua
18
candran.lua
|
|
@ -651,7 +651,6 @@ return requireStr .. lua(ast) .. newline()
|
|||
end
|
||||
end
|
||||
local lua53 = _() or lua53
|
||||
package["loaded"]["compiler.lua53"] = lua53 or true
|
||||
return lua53
|
||||
end
|
||||
local luajit = _() or luajit
|
||||
|
|
@ -1808,7 +1807,7 @@ return parser
|
|||
end
|
||||
local parser = _() or parser
|
||||
package["loaded"]["lib.lua-parser.parser"] = parser or true
|
||||
local candran = { ["VERSION"] = "0.3.0" }
|
||||
local candran = { ["VERSION"] = "0.3.1" }
|
||||
local default = {
|
||||
["target"] = "lua53", ["indentation"] = "", ["newline"] = "\
|
||||
", ["requirePrefix"] = "CANDRAN_", ["mapLines"] = true, ["chunkname"] = "nil", ["rewriteErrors"] = true
|
||||
|
|
@ -1836,25 +1835,26 @@ preprocessor = preprocessor .. "return output"
|
|||
local env = util["merge"](_G, options)
|
||||
env["candran"] = candran
|
||||
env["output"] = ""
|
||||
env["import"] = function(modpath, margs, autoRequire)
|
||||
env["import"] = function(modpath, margs)
|
||||
if margs == nil then margs = {} end
|
||||
if autoRequire == nil then autoRequire = true end
|
||||
local filepath = assert(util["search"](modpath), "No module named \"" .. modpath .. "\"")
|
||||
local f = io["open"](filepath)
|
||||
if not f then
|
||||
error("Can't open the module file to import")
|
||||
end
|
||||
margs = util["merge"](options, { ["chunkname"] = filepath }, margs)
|
||||
margs = util["merge"](options, {
|
||||
["chunkname"] = filepath, ["loadLocal"] = true, ["loadPackage"] = true
|
||||
}, margs)
|
||||
local modcontent = candran["preprocess"](f:read("*a"), margs)
|
||||
f:close()
|
||||
local modname = modpath:match("[^%.]+$")
|
||||
env["write"]("-- MODULE \"" .. modpath .. "\" --\
|
||||
env["write"]("-- MODULE " .. modpath .. " --\
|
||||
" .. "local function _()\
|
||||
" .. modcontent .. "\
|
||||
" .. "end\
|
||||
" .. (autoRequire and "local " .. modname .. " = _() or " .. modname .. "\
|
||||
" or "") .. "package.loaded[\"" .. modpath .. "\"] = " .. (autoRequire and modname or "_()") .. " or true\
|
||||
" .. "-- END OF MODULE \"" .. modpath .. "\" --")
|
||||
" .. (margs["loadLocal"] and ("local %s = _() or %s\
|
||||
"):format(modname, modname) or "") .. (margs["loadPackage"] and ("package.loaded[%q] = %s or true\
|
||||
"):format(modpath, margs["loadLocal"] and modname or "_()") or "") .. "-- END OF MODULE " .. modpath .. " --")
|
||||
end
|
||||
env["include"] = function(file)
|
||||
local f = io["open"](file)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ end
|
|||
|
||||
#local patch = output
|
||||
#output = ""
|
||||
#import("compiler.lua53", { patch = patch })
|
||||
#import("compiler.lua53", { patch = patch, loadPackage = false })
|
||||
|
||||
return lua53
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package = "Candran"
|
||||
|
||||
version = "0.3.0-1"
|
||||
version = "0.3.1-1"
|
||||
|
||||
description = {
|
||||
summary = "A simple Lua dialect and preprocessor.",
|
||||
|
|
@ -17,7 +17,7 @@ description = {
|
|||
|
||||
source = {
|
||||
url = "git://github.com/Reuh/Candran",
|
||||
tag = "v0.3.0"
|
||||
tag = "v0.3.1"
|
||||
}
|
||||
|
||||
dependencies = {
|
||||
202
test/test.lua
202
test/test.lua
|
|
@ -1,20 +1,16 @@
|
|||
print("========================")
|
||||
print("|| CANDRAN TESTS ||")
|
||||
print("========================")
|
||||
|
||||
local candran = dofile(arg[1] or "../candran.lua")
|
||||
|
||||
-- test helper
|
||||
local results = {} -- tests result
|
||||
local function test(name, candranCode, result, args)
|
||||
local function test(name, candranCode, expectedResult, options)
|
||||
results[name] = { result = "not finished", message = "no info" }
|
||||
local self = results[name]
|
||||
|
||||
-- make code
|
||||
local success, code = pcall(candran.make, candranCode, args)
|
||||
local success, code = pcall(candran.make, candranCode, options)
|
||||
if not success then
|
||||
self.result = "error"
|
||||
self.message = "error while making code :\n"..code
|
||||
self.message = "error while making code:\n"..code
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -22,7 +18,7 @@ local function test(name, candranCode, result, args)
|
|||
local success, func = pcall(loadstring or load, code)
|
||||
if not success then
|
||||
self.result = "error"
|
||||
self.message = "error while loading code :\n"..func
|
||||
self.message = "error while loading code:\n"..func
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -30,14 +26,14 @@ local function test(name, candranCode, result, args)
|
|||
local success, output = pcall(func)
|
||||
if not success then
|
||||
self.result = "error"
|
||||
self.message = "error while running code :\n"..output
|
||||
self.message = "error while running code:\n"..output
|
||||
return
|
||||
end
|
||||
|
||||
-- check result
|
||||
if output ~= result then
|
||||
if output ~= expectedResult then
|
||||
self.result = "fail"
|
||||
self.message = "invalid result from the code; it returned "..tostring(output).." instead of "..tostring(result)
|
||||
self.message = "invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult)
|
||||
return
|
||||
else
|
||||
self.result = "success"
|
||||
|
|
@ -48,10 +44,15 @@ end
|
|||
-- tests
|
||||
print("Running tests...")
|
||||
|
||||
------------------
|
||||
-- PREPROCESSOR --
|
||||
------------------
|
||||
|
||||
test("preprocessor", [[
|
||||
#local foo = true
|
||||
return true
|
||||
]], true)
|
||||
|
||||
test("preprocessor condition", [[
|
||||
#local foo = true
|
||||
#if not foo then
|
||||
|
|
@ -60,23 +61,45 @@ test("preprocessor condition", [[
|
|||
return true
|
||||
#end
|
||||
]], true)
|
||||
test("preprocessor args table", [[
|
||||
|
||||
test("preprocessor candran table", [[
|
||||
#write(("return %q"):format(candran.VERSION))
|
||||
]], candran.VERSION)
|
||||
|
||||
test("preprocessor output variable", [[
|
||||
#output = "return 5"
|
||||
]], 5)
|
||||
|
||||
test("preprocessor import function", [[
|
||||
#import("toInclude")
|
||||
return toInclude
|
||||
]], 5)
|
||||
|
||||
test("preprocessor include function", [[
|
||||
#include('toInclude.lua')
|
||||
]], 5)
|
||||
|
||||
test("preprocessor write function", [[
|
||||
#write("local a = true")
|
||||
return a
|
||||
]], true)
|
||||
|
||||
test("preprocessor placeholder function", [[
|
||||
#placeholder('foo')
|
||||
]], 5, { foo = "return 5" })
|
||||
|
||||
test("preprocessor options", [[
|
||||
#if not foo == "sky" then
|
||||
# error("Invalid foo argument")
|
||||
#end
|
||||
return true
|
||||
]], true, { foo = "sky" })
|
||||
test("preprocessor write function", [[
|
||||
#write("local a = true")
|
||||
return a
|
||||
]], true)
|
||||
test("preprocessor import function", [[
|
||||
#import("toInclude")
|
||||
return toInclude
|
||||
]], 5)
|
||||
test("preprocessor include function", "a = [[\n#include('toInclude.lua')\n]]\nreturn a",
|
||||
"local a = 5\nreturn a\n\n")
|
||||
|
||||
----------------------
|
||||
-- SYNTAX ADDITIONS --
|
||||
----------------------
|
||||
|
||||
-- Assignement operators
|
||||
test("+=", [[
|
||||
local a = 5
|
||||
a += 2
|
||||
|
|
@ -97,6 +120,11 @@ local a = 5
|
|||
a /= 2
|
||||
return a
|
||||
]], 5/2)
|
||||
test("//=", [[
|
||||
local a = 5
|
||||
a //= 2
|
||||
return a
|
||||
]], 2)
|
||||
test("^=", [[
|
||||
local a = 5
|
||||
a ^= 2
|
||||
|
|
@ -112,6 +140,72 @@ local a = "hello"
|
|||
a ..= " world"
|
||||
return a
|
||||
]], "hello world")
|
||||
test("and=", [[
|
||||
local a = true
|
||||
a and= "world"
|
||||
return a
|
||||
]], "world")
|
||||
test("or=", [[
|
||||
local a = false
|
||||
a or= "world"
|
||||
return a
|
||||
]], "world")
|
||||
test("&=", [[
|
||||
local a = 5
|
||||
a &= 3
|
||||
return a
|
||||
]], 1)
|
||||
test("|=", [[
|
||||
local a = 5
|
||||
a |= 3
|
||||
return a
|
||||
]], 7)
|
||||
test("<<=", [[
|
||||
local a = 23
|
||||
a <<= 2
|
||||
return a
|
||||
]], 92)
|
||||
test(">>=", [[
|
||||
local a = 23
|
||||
a >>= 2
|
||||
return a
|
||||
]], 5)
|
||||
|
||||
test("right assigments operators", [[
|
||||
local a = 5
|
||||
a =+ 2 assert(a == 7, "=+")
|
||||
a =- 2 assert(a == -5, "=-")
|
||||
a =* -2 assert(a == 10, "=*")
|
||||
a =/ 2 assert(a == 0.2, "=/")
|
||||
a =// 2 assert(a == 10, "=//")
|
||||
a =^ 2 assert(a == 1024, "=^")
|
||||
a =% 2000 assert(a == 976, "=%")
|
||||
|
||||
a = "world"
|
||||
a =.. "hello " assert(a == "hello world", "=..")
|
||||
a =and true assert(a == "hello world", "=and")
|
||||
|
||||
a = false
|
||||
a =or nil assert(a == false, "=or")
|
||||
|
||||
a = 3
|
||||
a =& 5 assert(a == 1, '=&')
|
||||
a =| 20 assert(a == 21, "=|")
|
||||
a =<< 1 assert(a == 2097152, "=<<")
|
||||
|
||||
a = 2
|
||||
a =>> 23 assert(a == 5, "=>>")
|
||||
]], nil)
|
||||
|
||||
test("some left+right assigments operators", [[
|
||||
local a = 5
|
||||
a -=+ 2 assert(a == 8, "-=+")
|
||||
|
||||
a = "hello"
|
||||
a ..=.. " world " assert(a == "hello world hello", "..=..")
|
||||
]], nil)
|
||||
|
||||
-- Default function parameters
|
||||
test("default parameters", [[
|
||||
local function test(hey, def="re", no, foo=("bar"):gsub("bar", "batru"))
|
||||
return def..foo
|
||||
|
|
@ -119,22 +213,68 @@ end
|
|||
return test(78, "SANDWICH", true)
|
||||
]], "SANDWICHbatru")
|
||||
|
||||
-- results
|
||||
print("=====================")
|
||||
print("|| RESULTS ||")
|
||||
print("=====================")
|
||||
-- @ self alias
|
||||
test("@ as self alias", [[
|
||||
local a = {}
|
||||
function a:hey()
|
||||
return @ == self
|
||||
end
|
||||
return a:hey()
|
||||
]], true)
|
||||
test("@ as self alias and indexation", [[
|
||||
local a = {
|
||||
foo = "Hoi"
|
||||
}
|
||||
function a:hey()
|
||||
return @.foo
|
||||
end
|
||||
return a:hey()
|
||||
]], "Hoi")
|
||||
test("@name indexation", [[
|
||||
local a = {
|
||||
foo = "Hoi"
|
||||
}
|
||||
function a:hey()
|
||||
return @foo
|
||||
end
|
||||
return a:hey()
|
||||
]], "Hoi")
|
||||
test("@[expt] indexation", [[
|
||||
local a = {
|
||||
foo = "Hoi"
|
||||
}
|
||||
function a:hey()
|
||||
return @["foo"]
|
||||
end
|
||||
return a:hey()
|
||||
]], "Hoi")
|
||||
|
||||
-- Short anonymous functions declaration
|
||||
test("short anonymous function declaration", [[
|
||||
local a = (arg1)
|
||||
return arg1
|
||||
end
|
||||
return a(5)
|
||||
]], 5)
|
||||
test("short anonymous method declaration", [[
|
||||
local a = :(arg1)
|
||||
return self + arg1
|
||||
end
|
||||
return a(2, 3)
|
||||
]], 5)
|
||||
|
||||
-- results
|
||||
local resultCounter = {}
|
||||
local testCounter = 0
|
||||
for name, test in pairs(results) do
|
||||
for name, t in pairs(results) do
|
||||
-- print errors & fails
|
||||
if test.result ~= "success" then
|
||||
print("Test \""..name.."\" : "..test.result)
|
||||
if test.message then print(test.message) end
|
||||
if t.result ~= "success" then
|
||||
print(name.." test: "..t.result)
|
||||
if t.message then print(t.message) end
|
||||
print("----------")
|
||||
end
|
||||
-- count tests results
|
||||
resultCounter[test.result] = (resultCounter[test.result] or 0) + 1
|
||||
resultCounter[t.result] = (resultCounter[t.result] or 0) + 1
|
||||
testCounter = testCounter + 1
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue