From b32d4d5600dac205e19fda66138e828f5cf0c76e Mon Sep 17 00:00:00 2001 From: Reuh Date: Fri, 18 Jun 2021 15:14:56 +0200 Subject: [PATCH] Update README --- README.md | 48 ++++++++++---- candran.lua | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 66992aa..78adb83 100644 --- a/README.md +++ b/README.md @@ -456,6 +456,7 @@ The preprocessor has access to the following variables: * ````write(...)````: write to the preprocessor output. For example, ````#write("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. * ```define(identifier, replacement)```: define a macro. See below. +* ```set(identifier, value)```: set a preprocessor constant. * each arguments passed to the preprocessor is directly available in the environment. * and every standard Lua library. @@ -526,23 +527,41 @@ The library can be used standalone through the ```canc``` (for compiling Candran Preprocess and compile each _filename_ Candran files, and creates the assiociated ```.lua``` files in the same directories. - _options_ is of type ````-somearg -anotherarg thing=somestring other=5````, which will generate a Lua table ```{ somearg = true, anotherarg = true, thing = "somestring", other = 5 }```. + _options_ is of type ````--no-map-lines -p --include module -d VAR 5````. - You can choose to use another directory where files should be written using the ```dest=destinationDirectory``` argument. + You can choose to use another directory where files should be written using the `--destination` or `-d` option: ```--destination destinationDirectory```. - You can choose the output filename using ```out=filename```. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. + You can choose the output filename using `--output` or `-o` option: `--output filename`. By default, compiled files have the same name as their input file, but with a ```.lua``` extension. - ```canc``` can write to the standard output instead of creating files using the ```-print``` argument. + ```canc``` can write to the standard output instead of creating files using the ```--print``` or `-p` argument. - You can choose to run only the preprocessor or compile using the ```-preprocess``` and ```-compile``` flags. + You can choose to run only the preprocessor or compile using the ```--preprocess``` and ```--compile``` flags. - You can choose to only parse the file and check it for syntaxic errors using the ```-parse``` flag. Errors will be printed to stderr in a similar format to ```luac -p```. + You can choose to only parse the file and check it for syntaxic errors using the ```--parse``` flag. Errors will be printed to stderr in a similar format to ```luac -p```. - The ```-ast``` flag is also available for debugging, and will disable preprocessing, compiling and file writing, and instead directly dump the AST generated from the input file(s) to stdout. + The ```--ast``` flag is also available for debugging, and will disable preprocessing, compiling and file writing, and instead directly dump the AST generated from the input file(s) to stdout. Instead of providing filenames, you can use ```-``` to read from standard input. - Use the ```-h``` or ```-help``` option to display a short help text. + You can change the compiler target using `--target` or `-t`: `--target luajit`. + + You can change the identation and newline string using `--indentation` and `--newline`: `--identation luajit`. + + You can change Candran's built-in variable prefix using `--variable-prefix`: `--variable-prefix __CAN_`. + + You can disable line mapping (error rewriting will not work) using `--no-map-lines`. + + You can disable built-in macros using `--no-builtin-macros`. + + You can define preprocessor constants using `--define` or `-D`: `--define VAR 5`. `VAR` will be available and set to 5 in the preprocessor. If you specify no value, it defaults to true. + + You can statically import modules using `--import` or `-I`: `--import module`. The module will be imported in compiled files using `#import("module",{loadLocal=false})`. + + You can disable error rewriting using `--no-rewrite-errors`. + + You can change the chunkname using `--chunkname`: `--chunkname filename`. This will change the filenames are reported in errors. By default, try to use the current file name, or stdin when using `-`. + + Use the ```-h``` or ```--help``` option to display the help text. Example uses: @@ -550,15 +569,15 @@ The library can be used standalone through the ```canc``` (for compiling Candran preprocess and compile _foo.can_ and write the result in _foo.lua_. - * ````canc indentation=" " foo.can```` + * ````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 -d verbose --print | lua```` - preprocess _foo.can_ with _verbose_ set to _true_, compile it and execute it. + preprocess _foo.can_ with _verbose_ set to _true_ in the preprocessor, compile it and execute it. - * ````canc -parse foo.can```` + * ````canc --parse foo.can```` checks foo.can for syntaxic errors. @@ -578,7 +597,9 @@ The library can be used standalone through the ```canc``` (for compiling Candran Instead of providing a filename, you can use ```-``` to read from standard input. - Use the ```-h``` or ```-help``` option to display a short help text. + Use similar options as `canc`. + + Use the ```-h``` or ```-help``` option to display the help text. * ```cancheck``` @@ -672,6 +693,7 @@ 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(). builtInMacros = true -- false to disable built-in macros __*__ preprocessorEnv = {} -- environment to merge with the preprocessor environement +import = {} -- list of modules to automatically import in compiled files (using #import("module",{loadLocal=false})) ``` You can change the defaults used for these variables in the table `candran.default`. diff --git a/candran.lua b/candran.lua index d09d73f..a7038d6 100644 --- a/candran.lua +++ b/candran.lua @@ -2220,6 +2220,14 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -3159,6 +3167,39 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -4102,6 +4143,67 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +targetName = "LuaJIT" -- ./compiler/luajit.can:1 +UNPACK = function(list, i, j) -- ./compiler/luajit.can:3 +return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:4 +end -- ./compiler/luajit.can:4 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897 @@ -5049,6 +5151,92 @@ end, -- ./compiler/lua54.can:876 }, { ["__index"] = function(self, key) -- ./compiler/lua54.can:889 error("don't know how to compile a " .. tostring(key) .. " to " .. targetName) -- ./compiler/lua54.can:890 end }) -- ./compiler/lua54.can:890 +targetName = "Lua 5.3" -- ./compiler/lua53.can:1 +tags["AttributeId"] = function(t) -- ./compiler/lua53.can:4 +if t[2] then -- ./compiler/lua53.can:5 +error("target " .. targetName .. " does not support variable attributes") -- ./compiler/lua53.can:6 +else -- ./compiler/lua53.can:6 +return t[1] -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +end -- ./compiler/lua53.can:8 +targetName = "Lua 5.2" -- ./compiler/lua52.can:1 +APPEND = function(t, toAppend) -- ./compiler/lua52.can:3 +return "do" .. indent() .. "local " .. var("a") .. ", " .. var("p") .. " = { " .. toAppend .. " }, #" .. t .. "+1" .. newline() .. "for i=1, #" .. var("a") .. " do" .. indent() .. t .. "[" .. var("p") .. "] = " .. var("a") .. "[i]" .. newline() .. "" .. var("p") .. " = " .. var("p") .. " + 1" .. unindent() .. "end" .. unindent() .. "end" -- ./compiler/lua52.can:4 +end -- ./compiler/lua52.can:4 +tags["_opid"]["idiv"] = function(left, right) -- ./compiler/lua52.can:7 +return "math.floor(" .. lua(left) .. " / " .. lua(right) .. ")" -- ./compiler/lua52.can:8 +end -- ./compiler/lua52.can:8 +tags["_opid"]["band"] = function(left, right) -- ./compiler/lua52.can:10 +return "bit32.band(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:11 +end -- ./compiler/lua52.can:11 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/lua52.can:13 +return "bit32.bor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:14 +end -- ./compiler/lua52.can:14 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/lua52.can:16 +return "bit32.bxor(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:17 +end -- ./compiler/lua52.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/lua52.can:19 +return "bit32.lshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:20 +end -- ./compiler/lua52.can:20 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/lua52.can:22 +return "bit32.rshift(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/lua52.can:23 +end -- ./compiler/lua52.can:23 +tags["_opid"]["bnot"] = function(right) -- ./compiler/lua52.can:25 +return "bit32.bnot(" .. lua(right) .. ")" -- ./compiler/lua52.can:26 +end -- ./compiler/lua52.can:26 +targetName = "LuaJIT" -- ./compiler/luajit.can:1 +UNPACK = function(list, i, j) -- ./compiler/luajit.can:3 +return "unpack(" .. list .. (i and (", " .. i .. (j and (", " .. j) or "")) or "") .. ")" -- ./compiler/luajit.can:4 +end -- ./compiler/luajit.can:4 +tags["_opid"]["band"] = function(left, right) -- ./compiler/luajit.can:7 +addRequire("bit", "band", "band") -- ./compiler/luajit.can:8 +return var("band") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:9 +end -- ./compiler/luajit.can:9 +tags["_opid"]["bor"] = function(left, right) -- ./compiler/luajit.can:11 +addRequire("bit", "bor", "bor") -- ./compiler/luajit.can:12 +return var("bor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:13 +end -- ./compiler/luajit.can:13 +tags["_opid"]["bxor"] = function(left, right) -- ./compiler/luajit.can:15 +addRequire("bit", "bxor", "bxor") -- ./compiler/luajit.can:16 +return var("bxor") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:17 +end -- ./compiler/luajit.can:17 +tags["_opid"]["shl"] = function(left, right) -- ./compiler/luajit.can:19 +addRequire("bit", "lshift", "lshift") -- ./compiler/luajit.can:20 +return var("lshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:21 +end -- ./compiler/luajit.can:21 +tags["_opid"]["shr"] = function(left, right) -- ./compiler/luajit.can:23 +addRequire("bit", "rshift", "rshift") -- ./compiler/luajit.can:24 +return var("rshift") .. "(" .. lua(left) .. ", " .. lua(right) .. ")" -- ./compiler/luajit.can:25 +end -- ./compiler/luajit.can:25 +tags["_opid"]["bnot"] = function(right) -- ./compiler/luajit.can:27 +addRequire("bit", "bnot", "bnot") -- ./compiler/luajit.can:28 +return var("bnot") .. "(" .. lua(right) .. ")" -- ./compiler/luajit.can:29 +end -- ./compiler/luajit.can:29 +targetName = "Lua 5.1" -- ./compiler/lua51.can:1 +states["continue"] = {} -- ./compiler/lua51.can:3 +CONTINUE_START = function() -- ./compiler/lua51.can:5 +return "local " .. var("break") .. newline() .. "repeat" .. indent() .. push("continue", var("break")) -- ./compiler/lua51.can:6 +end -- ./compiler/lua51.can:6 +CONTINUE_STOP = function() -- ./compiler/lua51.can:8 +return pop("continue") .. unindent() .. "until true" .. newline() .. "if " .. var("break") .. " then break end" -- ./compiler/lua51.can:9 +end -- ./compiler/lua51.can:9 +tags["Continue"] = function() -- ./compiler/lua51.can:12 +return "break" -- ./compiler/lua51.can:13 +end -- ./compiler/lua51.can:13 +tags["Break"] = function() -- ./compiler/lua51.can:15 +local inContinue = peek("continue") -- ./compiler/lua51.can:16 +if inContinue then -- ./compiler/lua51.can:17 +return inContinue .. " = true" .. newline() .. "break" -- ./compiler/lua51.can:18 +else -- ./compiler/lua51.can:18 +return "break" -- ./compiler/lua51.can:20 +end -- ./compiler/lua51.can:20 +end -- ./compiler/lua51.can:20 +tags["Goto"] = function() -- ./compiler/lua51.can:25 +error("target " .. targetName .. " does not support gotos") -- ./compiler/lua51.can:26 +end -- ./compiler/lua51.can:26 +tags["Label"] = function() -- ./compiler/lua51.can:28 +error("target " .. targetName .. " does not support goto labels") -- ./compiler/lua51.can:29 +end -- ./compiler/lua51.can:29 local code = lua(ast) .. newline() -- ./compiler/lua54.can:896 return requireStr .. code -- ./compiler/lua54.can:897 end -- ./compiler/lua54.can:897