Fennel is now embeded

This commit is contained in:
perro tuerto 2023-03-07 14:57:14 -08:00
parent a36006cee2
commit ab643376b1
4 changed files with 924 additions and 1449 deletions

View File

@ -1,11 +1,11 @@
# Variables
NAME="fennel-1.3.0"
URL="https://fennel-lang.org/downloads/$NAME"
ASC="https://fennel-lang.org/downloads/$NAME.asc"
DIR=$(git rev-parse --show-toplevel)
ROOT=$(git rev-parse --show-toplevel)
URL="https://fennel-lang.org/downloads/$NAME.tar.gz"
# Copies Fennel from release tarball
cd $DIR/src
curl -o fennel $URL
chmod +x fennel
cd $ROOT/src
curl -O $URL
tar -xvzf $NAME.tar.gz
mv $NAME/fennel.lua .
rm -rf $NAME*

577
src/fennel → src/fennel.lua Executable file → Normal file
View File

@ -1,217 +1,3 @@
#!/usr/bin/env lua
package.preload["fennel.binary"] = package.preload["fennel.binary"] or function(...)
local fennel = require("fennel")
local _local_787_ = require("fennel.utils")
local warn = _local_787_["warn"]
local copy = _local_787_["copy"]
local function shellout(command)
local f = io.popen(command)
local stdout = f:read("*all")
return (f:close() and stdout)
end
local function execute(cmd)
local _788_ = os.execute(cmd)
if (_788_ == 0) then
return true
elseif (_788_ == true) then
return true
else
return nil
end
end
local function string__3ec_hex_literal(characters)
local hex = {}
for character in characters:gmatch(".") do
table.insert(hex, ("0x%02x"):format(string.byte(character)))
end
return table.concat(hex, ", ")
end
local c_shim = "#ifdef __cplusplus\nextern \"C\" {\n#endif\n#include <lauxlib.h>\n#include <lua.h>\n#include <lualib.h>\n#ifdef __cplusplus\n}\n#endif\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#if LUA_VERSION_NUM == 501\n #define LUA_OK 0\n#endif\n\n/* Copied from lua.c */\n\nstatic lua_State *globalL = NULL;\n\nstatic void lstop (lua_State *L, lua_Debug *ar) {\n (void)ar; /* unused arg. */\n lua_sethook(L, NULL, 0, 0); /* reset hook */\n luaL_error(L, \"interrupted!\");\n}\n\nstatic void laction (int i) {\n signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */\n lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);\n}\n\nstatic void createargtable (lua_State *L, char **argv, int argc, int script) {\n int i, narg;\n if (script == argc) script = 0; /* no script name? */\n narg = argc - (script + 1); /* number of positive indices */\n lua_createtable(L, narg, script + 1);\n for (i = 0; i < argc; i++) {\n lua_pushstring(L, argv[i]);\n lua_rawseti(L, -2, i - script);\n }\n lua_setglobal(L, \"arg\");\n}\n\nstatic int msghandler (lua_State *L) {\n const char *msg = lua_tostring(L, 1);\n if (msg == NULL) { /* is error object not a string? */\n if (luaL_callmeta(L, 1, \"__tostring\") && /* does it have a metamethod */\n lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */\n return 1; /* that is the message */\n else\n msg = lua_pushfstring(L, \"(error object is a %%s value)\",\n luaL_typename(L, 1));\n }\n /* Call debug.traceback() instead of luaL_traceback() for Lua 5.1 compat. */\n lua_getglobal(L, \"debug\");\n lua_getfield(L, -1, \"traceback\");\n /* debug */\n lua_remove(L, -2);\n lua_pushstring(L, msg);\n /* original msg */\n lua_remove(L, -3);\n lua_pushinteger(L, 2); /* skip this function and traceback */\n lua_call(L, 2, 1); /* call debug.traceback */\n return 1; /* return the traceback */\n}\n\nstatic int docall (lua_State *L, int narg, int nres) {\n int status;\n int base = lua_gettop(L) - narg; /* function index */\n lua_pushcfunction(L, msghandler); /* push message handler */\n lua_insert(L, base); /* put it under function and args */\n globalL = L; /* to be available to 'laction' */\n signal(SIGINT, laction); /* set C-signal handler */\n status = lua_pcall(L, narg, nres, base);\n signal(SIGINT, SIG_DFL); /* reset C-signal handler */\n lua_remove(L, base); /* remove message handler from the stack */\n return status;\n}\n\nint main(int argc, char *argv[]) {\n lua_State *L = luaL_newstate();\n luaL_openlibs(L);\n createargtable(L, argv, argc, 0);\n\n static const unsigned char lua_loader_program[] = {\n%s\n};\n if(luaL_loadbuffer(L, (const char*)lua_loader_program,\n sizeof(lua_loader_program), \"%s\") != LUA_OK) {\n fprintf(stderr, \"luaL_loadbuffer: %%s\\n\", lua_tostring(L, -1));\n lua_close(L);\n return 1;\n }\n\n /* lua_bundle */\n lua_newtable(L);\n static const unsigned char lua_require_1[] = {\n %s\n };\n lua_pushlstring(L, (const char*)lua_require_1, sizeof(lua_require_1));\n lua_setfield(L, -2, \"%s\");\n\n%s\n\n if (docall(L, 1, LUA_MULTRET)) {\n const char *errmsg = lua_tostring(L, 1);\n if (errmsg) {\n fprintf(stderr, \"%%s\\n\", errmsg);\n }\n lua_close(L);\n return 1;\n }\n lua_close(L);\n return 0;\n}"
local function compile_fennel(filename, options)
local f
if (filename == "-") then
f = io.stdin
else
f = assert(io.open(filename, "rb"))
end
local lua_code = fennel["compile-string"](f:read("*a"), options)
f:close()
return lua_code
end
local function module_name(open, rename, used_renames)
local require_name
do
local _791_ = rename[open]
if (nil ~= _791_) then
local renamed = _791_
used_renames[open] = true
require_name = renamed
elseif true then
local _ = _791_
require_name = open
else
require_name = nil
end
end
return (require_name:sub(1, 1) .. require_name:sub(2):gsub("_", "."))
end
local function native_loader(native, _3foptions)
local opts = (_3foptions or {["rename-modules"] = {}})
local rename = (opts["rename-modules"] or {})
local used_renames = {}
local nm = (os.getenv("NM") or "nm")
local out = {" /* native libraries */"}
for _, path in ipairs(native) do
local opens = {}
for open in shellout((nm .. " " .. path)):gmatch("[^dDt] _?luaopen_([%a%p%d]+)") do
table.insert(opens, open)
end
if (0 == #opens) then
warn((("Native module %s did not contain any luaopen_* symbols. " .. "Did you mean to use --native-library instead of --native-module?")):format(path))
else
end
for _0, open in ipairs(opens) do
table.insert(out, (" int luaopen_%s(lua_State *L);"):format(open))
table.insert(out, (" lua_pushcfunction(L, luaopen_%s);"):format(open))
table.insert(out, (" lua_setfield(L, -2, \"%s\");\n"):format(module_name(open, rename, used_renames)))
end
end
for key, val in pairs(rename) do
if not used_renames[key] then
warn((("unused --rename-native-module %s %s argument. " .. "Did you mean to include a native module?")):format(key, val))
else
end
end
return table.concat(out, "\n")
end
local function fennel__3ec(filename, native, options)
local basename = filename:gsub("(.*[\\/])(.*)", "%2")
local basename_noextension = (basename:match("(.+)%.") or basename)
local dotpath = filename:gsub("^%.%/", ""):gsub("[\\/]", ".")
local dotpath_noextension = (dotpath:match("(.+)%.") or dotpath)
local fennel_loader
local _795_
do
_795_ = "(do (local bundle_2_auto ...) (fn loader_3_auto [name_4_auto] (match (or (. bundle_2_auto name_4_auto) (. bundle_2_auto (.. name_4_auto \".init\"))) (mod_5_auto ? (= \"function\" (type mod_5_auto))) mod_5_auto (mod_5_auto ? (= \"string\" (type mod_5_auto))) (assert (if (= _VERSION \"Lua 5.1\") (loadstring mod_5_auto name_4_auto) (load mod_5_auto name_4_auto))) nil (values nil (: \"\n\\tmodule '%%s' not found in fennel bundle\" \"format\" name_4_auto)))) (table.insert (or package.loaders package.searchers) 2 loader_3_auto) ((assert (loader_3_auto \"%s\")) ((or unpack table.unpack) arg)))"
end
fennel_loader = _795_:format(dotpath_noextension)
local lua_loader = fennel["compile-string"](fennel_loader)
local _let_796_ = options
local rename_modules = _let_796_["rename-modules"]
return c_shim:format(string__3ec_hex_literal(lua_loader), basename_noextension, string__3ec_hex_literal(compile_fennel(filename, options)), dotpath_noextension, native_loader(native, {["rename-modules"] = rename_modules}))
end
local function write_c(filename, native, options)
local out_filename = (filename .. "_binary.c")
local f = assert(io.open(out_filename, "w+"))
f:write(fennel__3ec(filename, native, options))
f:close()
return out_filename
end
local function compile_binary(lua_c_path, executable_name, static_lua, lua_include_dir, native)
local cc = (os.getenv("CC") or "cc")
local rdynamic, bin_extension, ldl_3f = nil, nil, nil
local _798_
do
local _797_ = shellout((cc .. " -dumpmachine"))
if (nil ~= _797_) then
_798_ = _797_:match("mingw")
else
_798_ = _797_
end
end
if _798_ then
rdynamic, bin_extension, ldl_3f = "", ".exe", false
else
rdynamic, bin_extension, ldl_3f = "-rdynamic", "", true
end
local compile_command
local _801_
if ldl_3f then
_801_ = "-ldl"
else
_801_ = ""
end
compile_command = {cc, "-Os", lua_c_path, table.concat(native, " "), static_lua, rdynamic, "-lm", _801_, "-o", (executable_name .. bin_extension), "-I", lua_include_dir, os.getenv("CC_OPTS")}
if os.getenv("FENNEL_DEBUG") then
print("Compiling with", table.concat(compile_command, " "))
else
end
if not execute(table.concat(compile_command, " ")) then
print("failed:", table.concat(compile_command, " "))
os.exit(1)
else
end
if not os.getenv("FENNEL_DEBUG") then
os.remove(lua_c_path)
else
end
return os.exit(0)
end
local function native_path_3f(path)
local extension, version_extension = path:match("%.(%a+)(%.?%d*)$")
if (version_extension and (version_extension ~= "") and not version_extension:match("%.%d+")) then
return false
else
local _806_ = extension
if (_806_ == "a") then
return path
elseif (_806_ == "o") then
return path
elseif (_806_ == "so") then
return path
elseif (_806_ == "dylib") then
return path
elseif true then
local _ = _806_
return false
else
return nil
end
end
end
local function extract_native_args(args)
local native = {modules = {}, libraries = {}, ["rename-modules"] = {}}
for i = #args, 1, -1 do
if ("--native-module" == args[i]) then
local path = assert(native_path_3f(table.remove(args, (i + 1))))
table.insert(native.modules, 1, path)
table.insert(native.libraries, 1, path)
table.remove(args, i)
else
end
if ("--native-library" == args[i]) then
table.insert(native.libraries, 1, assert(native_path_3f(table.remove(args, (i + 1)))))
table.remove(args, i)
else
end
if ("--rename-native-module" == args[i]) then
local original = table.remove(args, (i + 1))
local new = table.remove(args, (i + 1))
do end (native["rename-modules"])[original] = new
table.remove(args, i)
else
end
end
if (0 < #args) then
print(table.concat(args, " "))
error(("Unknown args: " .. table.concat(args, " ")))
else
end
return native
end
local function compile(filename, executable_name, static_lua, lua_include_dir, options, args)
local _let_813_ = extract_native_args(args)
local modules = _let_813_["modules"]
local libraries = _let_813_["libraries"]
local rename_modules = _let_813_["rename-modules"]
local opts = {["rename-modules"] = rename_modules}
copy(options, opts)
return compile_binary(write_c(filename, modules, opts), executable_name, static_lua, lua_include_dir, libraries)
end
local help = "\nUsage: %s --compile-binary FILE OUT STATIC_LUA_LIB LUA_INCLUDE_DIR\n\nCompile a binary from your Fennel program.\n\nRequires a C compiler, a copy of liblua, and Lua's dev headers. Implies\nthe --require-as-include option.\n\n FILE: the Fennel source being compiled.\n OUT: the name of the executable to generate\n STATIC_LUA_LIB: the path to the Lua library to use in the executable\n LUA_INCLUDE_DIR: the path to the directory of Lua C header files\n\nFor example, on a Debian system, to compile a file called program.fnl using\nLua 5.3, you would use this:\n\n $ %s --compile-binary program.fnl program \\\n /usr/lib/x86_64-linux-gnu/liblua5.3.a /usr/include/lua5.3\n\nThe program will be compiled to Lua, then compiled to C, then compiled to\nmachine code. You can set the CC environment variable to change the compiler\nused (default: cc) or set CC_OPTS to pass in compiler options. For example\nset CC_OPTS=-static to generate a binary with static linking.\n\nThis method is currently limited to programs do not transitively require Lua\nmodules. Requiring a Lua module directly will work, but requiring a Lua module\nwhich requires another will fail.\n\nTo include C libraries that contain Lua modules, add --native-module path/to.so,\nand to include C libraries without modules, use --native-library path/to.so.\nThese options are unstable, barely tested, and even more likely to break.\n\nIf you need to change the require name that a given native module is referenced\nas, you can use the --rename-native-module ORIGINAL NEW. ORIGINAL should be the\nsuffix of the luaopen_* symbol in the native module. NEW should be the string\nyou wish to pass to require to require the given native module. This can be used\nto handle cases where the name of an object file does not match the name of the\nluaopen_* symbol(s) within it. For example, the Lua readline bindings include a\nreadline.lua file which is usually required as \"readline\", and a C-readline.so\nfile which is required in the Lua half of the bindings like so:\n\n require 'C-readline'\n\nHowever, the symbol within the C-readline.so file is named luaopen_readline, so\nby default --compile-binary will make it so you can require it as \"readline\",\nwhich collides with the name of the readline.lua file and doesn't match the\nrequire call within readline.lua. In order to include the module within your\ncompiled binary and have it get picked up by readline.lua correctly, you can\nspecify the name used to refer to it in a require call by compiling it like\nso (this is assuming that program.fnl requires the Lua bindings):\n\n $ %s --compile-binary program.fnl program \\\n /usr/lib/x86_64-linux-gnu/liblua5.3.a /usr/include/lua5.3 \\\n --native-module C-readline.so \\\n --rename-native-module readline C-readline\n"
return {compile = compile, help = help}
end
local fennel
package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...)
local utils = require("fennel.utils")
local parser = require("fennel.parser")
@ -4346,6 +4132,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function(
end
return {granulate = granulate, parser = parser, ["string-stream"] = string_stream, ["sym-char?"] = sym_char_3f}
end
local utils
package.preload["fennel.view"] = package.preload["fennel.view"] or function(...)
local type_order = {number = 1, boolean = 2, string = 3, table = 4, ["function"] = 5, userdata = 6, thread = 7}
local default_opts = {["one-line?"] = false, ["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["metamethod?"] = true, ["prefer-colon?"] = false, ["escape-newlines?"] = false, ["utf8?"] = true, ["line-length"] = 80, depth = 128, ["max-sparse-gap"] = 10}
@ -5545,14 +5332,13 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(..
end
return {warn = warn, allpairs = allpairs, stablepairs = stablepairs, copy = copy, ["get-in"] = get_in, kvmap = kvmap, map = map, ["walk-tree"] = walk_tree, ["member?"] = member_3f, maxn = maxn, ["every?"] = every_3f, list = list, sequence = sequence, sym = sym, varg = varg, expr = expr, comment = comment_2a, ["comment?"] = comment_3f, ["expr?"] = expr_3f, ["list?"] = list_3f, ["multi-sym?"] = multi_sym_3f, ["sequence?"] = sequence_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["varg?"] = varg_3f, ["quoted?"] = quoted_3f, ["string?"] = string_3f, ["idempotent-expr?"] = idempotent_expr_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["lua-keywords"] = lua_keywords, hook = hook, ["hook-opts"] = hook_opts, ["propagate-options"] = propagate_options, root = root, ["debug-on?"] = debug_on_3f, ["ast-source"] = ast_source, version = version, ["runtime-version"] = runtime_version, len = len, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";")}
end
package.preload["fennel"] = package.preload["fennel"] or function(...)
local utils = require("fennel.utils")
local parser = require("fennel.parser")
local compiler = require("fennel.compiler")
local specials = require("fennel.specials")
local repl = require("fennel.repl")
local view = require("fennel.view")
local function eval_env(env, opts)
utils = require("fennel.utils")
local parser = require("fennel.parser")
local compiler = require("fennel.compiler")
local specials = require("fennel.specials")
local repl = require("fennel.repl")
local view = require("fennel.view")
local function eval_env(env, opts)
if (env == "_COMPILER") then
local env0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}, opts)
if (opts.allowedGlobals == nil) then
@ -5563,8 +5349,8 @@ package.preload["fennel"] = package.preload["fennel"] or function(...)
else
return (env and specials["wrap-env"](env))
end
end
local function eval_opts(options, str)
end
local function eval_opts(options, str)
local opts = utils.copy(options)
if (opts.allowedGlobals == nil) then
opts.allowedGlobals = specials["current-global-names"](opts.env)
@ -5579,8 +5365,8 @@ package.preload["fennel"] = package.preload["fennel"] or function(...)
else
end
return opts
end
local function eval(str, options, ...)
end
local function eval(str, options, ...)
local opts = eval_opts(options, str)
local env = eval_env(opts.env, opts)
local lua_source = compiler["compile-string"](str, opts)
@ -5595,16 +5381,16 @@ package.preload["fennel"] = package.preload["fennel"] or function(...)
loader = specials["load-code"](lua_source, env, _753_(...))
opts.filename = nil
return loader(...)
end
local function dofile_2a(filename, options, ...)
end
local function dofile_2a(filename, options, ...)
local opts = utils.copy(options)
local f = assert(io.open(filename, "rb"))
local source = assert(f:read("*all"), ("Could not read " .. filename))
f:close()
opts.filename = filename
return eval(source, opts, ...)
end
local function syntax()
end
local function syntax()
local body_3f = {"when", "with-open", "collect", "icollect", "fcollect", "lambda", "\206\187", "macro", "match", "match-try", "case", "case-try", "accumulate", "faccumulate", "doto"}
local binding_3f = {"collect", "icollect", "fcollect", "each", "for", "let", "with-open", "accumulate", "faccumulate"}
local define_3f = {"fn", "lambda", "\206\187", "var", "local", "macro", "macros", "global"}
@ -5632,14 +5418,14 @@ package.preload["fennel"] = package.preload["fennel"] or function(...)
end
end
return out
end
local mod = {list = utils.list, ["list?"] = utils["list?"], sym = utils.sym, ["sym?"] = utils["sym?"], ["multi-sym?"] = utils["multi-sym?"], sequence = utils.sequence, ["sequence?"] = utils["sequence?"], ["table?"] = utils["table?"], comment = utils.comment, ["comment?"] = utils["comment?"], varg = utils.varg, ["varg?"] = utils["varg?"], ["sym-char?"] = parser["sym-char?"], parser = parser.parser, compile = compiler.compile, ["compile-string"] = compiler["compile-string"], ["compile-stream"] = compiler["compile-stream"], eval = eval, repl = repl, view = view, dofile = dofile_2a, ["load-code"] = specials["load-code"], doc = specials.doc, metadata = compiler.metadata, traceback = compiler.traceback, version = utils.version, ["runtime-version"] = utils["runtime-version"], ["ast-source"] = utils["ast-source"], path = utils.path, ["macro-path"] = utils["macro-path"], ["macro-loaded"] = specials["macro-loaded"], ["macro-searchers"] = specials["macro-searchers"], ["search-module"] = specials["search-module"], ["make-searcher"] = specials["make-searcher"], searcher = specials["make-searcher"](), syntax = syntax, gensym = compiler.gensym, scope = compiler["make-scope"], mangle = compiler["global-mangling"], unmangle = compiler["global-unmangling"], compile1 = compiler.compile1, ["string-stream"] = parser["string-stream"], granulate = parser.granulate, loadCode = specials["load-code"], make_searcher = specials["make-searcher"], makeSearcher = specials["make-searcher"], searchModule = specials["search-module"], macroPath = utils["macro-path"], macroSearchers = specials["macro-searchers"], macroLoaded = specials["macro-loaded"], compileStream = compiler["compile-stream"], compileString = compiler["compile-string"], stringStream = parser["string-stream"], runtimeVersion = utils["runtime-version"]}
mod.install = function(_3fopts)
end
local mod = {list = utils.list, ["list?"] = utils["list?"], sym = utils.sym, ["sym?"] = utils["sym?"], ["multi-sym?"] = utils["multi-sym?"], sequence = utils.sequence, ["sequence?"] = utils["sequence?"], ["table?"] = utils["table?"], comment = utils.comment, ["comment?"] = utils["comment?"], varg = utils.varg, ["varg?"] = utils["varg?"], ["sym-char?"] = parser["sym-char?"], parser = parser.parser, compile = compiler.compile, ["compile-string"] = compiler["compile-string"], ["compile-stream"] = compiler["compile-stream"], eval = eval, repl = repl, view = view, dofile = dofile_2a, ["load-code"] = specials["load-code"], doc = specials.doc, metadata = compiler.metadata, traceback = compiler.traceback, version = utils.version, ["runtime-version"] = utils["runtime-version"], ["ast-source"] = utils["ast-source"], path = utils.path, ["macro-path"] = utils["macro-path"], ["macro-loaded"] = specials["macro-loaded"], ["macro-searchers"] = specials["macro-searchers"], ["search-module"] = specials["search-module"], ["make-searcher"] = specials["make-searcher"], searcher = specials["make-searcher"](), syntax = syntax, gensym = compiler.gensym, scope = compiler["make-scope"], mangle = compiler["global-mangling"], unmangle = compiler["global-unmangling"], compile1 = compiler.compile1, ["string-stream"] = parser["string-stream"], granulate = parser.granulate, loadCode = specials["load-code"], make_searcher = specials["make-searcher"], makeSearcher = specials["make-searcher"], searchModule = specials["search-module"], macroPath = utils["macro-path"], macroSearchers = specials["macro-searchers"], macroLoaded = specials["macro-loaded"], compileStream = compiler["compile-stream"], compileString = compiler["compile-string"], stringStream = parser["string-stream"], runtimeVersion = utils["runtime-version"]}
mod.install = function(_3fopts)
table.insert((package.searchers or package.loaders), specials["make-searcher"](_3fopts))
return mod
end
utils["fennel-module"] = mod
do
end
utils["fennel-module"] = mod
do
local module_name = "fennel.macros"
local _
local function _757_()
@ -6457,322 +6243,5 @@ package.preload["fennel"] = package.preload["fennel"] or function(...)
compiler.scopes.global.macros[k] = v
end
package.preload[module_name] = nil
end
return mod
end
fennel = require("fennel")
local unpack = (table.unpack or _G.unpack)
local help = "\nUsage: fennel [FLAG] [FILE]\n\nRun fennel, a lisp programming language for the Lua runtime.\n\n --repl : Command to launch an interactive repl session\n --compile FILES (-c) : Command to AOT compile files, writing Lua to stdout\n --eval SOURCE (-e) : Command to evaluate source code and print the result\n\n --no-searcher : Skip installing package.searchers entry\n --indent VAL : Indent compiler output with VAL\n --add-package-path PATH : Add PATH to package.path for finding Lua modules\n --add-fennel-path PATH : Add PATH to fennel.path for finding Fennel modules\n --add-macro-path PATH : Add PATH to fennel.macro-path for macro modules\n --globals G1[,G2...] : Allow these globals in addition to standard ones\n --globals-only G1[,G2] : Same as above, but exclude standard ones\n --require-as-include : Inline required modules in the output\n --skip-include M1[,M2] : Omit certain modules from output when included\n --use-bit-lib : Use LuaJITs bit library instead of operators\n --metadata : Enable function metadata, even in compiled output\n --no-metadata : Disable function metadata, even in REPL\n --correlate : Make Lua output line numbers match Fennel input\n --load FILE (-l) : Load the specified FILE before executing the command\n --lua LUA_EXE : Run in a child process with LUA_EXE\n --no-fennelrc : Skip loading ~/.fennelrc when launching repl\n --raw-errors : Disable friendly compile error reporting\n --plugin FILE : Activate the compiler plugin in FILE\n --compile-binary FILE\n OUT LUA_LIB LUA_DIR : Compile FILE to standalone binary OUT\n --compile-binary --help : Display further help for compiling binaries\n --no-compiler-sandbox : Do not limit compiler environment to minimal sandbox\n\n --help (-h) : Display this text\n --version (-v) : Show version\n\nGlobals are not checked when doing AOT (ahead-of-time) compilation unless\nthe --globals-only or --globals flag is provided. Use --globals \"*\" to disable\nstrict globals checking in other contexts.\n\nMetadata is typically considered a development feature and is not recommended\nfor production. It is used for docstrings and enabled by default in the REPL.\n\nWhen not given a command, runs the file given as the first argument.\nWhen given neither command nor file, launches a repl.\n\nUse the NO_COLOR environment variable to disable escape codes in error messages.\n\nIf ~/.fennelrc exists, it will be loaded before launching a repl."
local options = {plugins = {}}
local function pack(...)
local _759_ = {...}
_759_["n"] = select("#", ...)
return _759_
end
local function dosafely(f, ...)
local args = {...}
local result
local function _760_()
return f(unpack(args))
end
result = pack(xpcall(_760_, fennel.traceback))
if not result[1] then
do end (io.stderr):write((result[2] .. "\n"))
os.exit(1)
else
end
return unpack(result, 2, result.n)
end
local function allow_globals(names, actual_globals)
if (names == "*") then
options.allowedGlobals = false
return nil
else
do
local tbl_16_auto = {}
local i_17_auto = #tbl_16_auto
for g in names:gmatch("([^,]+),?") do
local val_18_auto = g
if (nil ~= val_18_auto) then
i_17_auto = (i_17_auto + 1)
do end (tbl_16_auto)[i_17_auto] = val_18_auto
else
end
end
options.allowedGlobals = tbl_16_auto
end
for global_name in pairs(actual_globals) do
table.insert(options.allowedGlobals, global_name)
end
return nil
end
end
local function handle_load(i)
local file = table.remove(arg, (i + 1))
dosafely(fennel.dofile, file, options)
return table.remove(arg, i)
end
local function handle_lua(i)
table.remove(arg, i)
local tgt_lua = table.remove(arg, i)
local cmd = {string.format("%s %s", tgt_lua, (arg[0] or "fennel"))}
for i0 = 1, #arg do
table.insert(cmd, string.format("%q", arg[i0]))
end
local ok = os.execute(table.concat(cmd, " "))
local _764_
if ok then
_764_ = 0
else
_764_ = 1
end
return os.exit(_764_, true)
end
assert(arg, "Using the launcher from non-CLI context; use fennel.lua instead.")
for i = #arg, 1, -1 do
local _766_ = arg[i]
if (_766_ == "--lua") then
handle_lua(i)
else
end
end
do
local commands = {["--repl"] = true, ["--compile"] = true, ["-c"] = true, ["--compile-binary"] = true, ["--eval"] = true, ["-e"] = true, ["-v"] = true, ["--version"] = true, ["--help"] = true, ["-h"] = true, ["-"] = true}
local i = 1
while (arg[i] and not options["ignore-options"]) do
local _768_ = arg[i]
if (_768_ == "--no-searcher") then
options["no-searcher"] = true
table.remove(arg, i)
elseif (_768_ == "--indent") then
options.indent = table.remove(arg, (i + 1))
if (options.indent == "false") then
options.indent = false
else
end
table.remove(arg, i)
elseif (_768_ == "--add-package-path") then
local entry = table.remove(arg, (i + 1))
package.path = (entry .. ";" .. package.path)
table.remove(arg, i)
elseif (_768_ == "--add-fennel-path") then
local entry = table.remove(arg, (i + 1))
fennel.path = (entry .. ";" .. fennel.path)
table.remove(arg, i)
elseif (_768_ == "--add-macro-path") then
local entry = table.remove(arg, (i + 1))
fennel["macro-path"] = (entry .. ";" .. fennel["macro-path"])
table.remove(arg, i)
elseif (_768_ == "--load") then
handle_load(i)
elseif (_768_ == "-l") then
handle_load(i)
elseif (_768_ == "--no-fennelrc") then
options.fennelrc = false
table.remove(arg, i)
elseif (_768_ == "--correlate") then
options.correlate = true
table.remove(arg, i)
elseif (_768_ == "--check-unused-locals") then
options.checkUnusedLocals = true
table.remove(arg, i)
elseif (_768_ == "--globals") then
allow_globals(table.remove(arg, (i + 1)), _G)
table.remove(arg, i)
elseif (_768_ == "--globals-only") then
allow_globals(table.remove(arg, (i + 1)), {})
table.remove(arg, i)
elseif (_768_ == "--require-as-include") then
options.requireAsInclude = true
table.remove(arg, i)
elseif (_768_ == "--skip-include") then
local skip_names = table.remove(arg, (i + 1))
local skip
do
local tbl_16_auto = {}
local i_17_auto = #tbl_16_auto
for m in skip_names:gmatch("([^,]+)") do
local val_18_auto = m
if (nil ~= val_18_auto) then
i_17_auto = (i_17_auto + 1)
do end (tbl_16_auto)[i_17_auto] = val_18_auto
else
end
end
skip = tbl_16_auto
end
options.skipInclude = skip
table.remove(arg, i)
elseif (_768_ == "--use-bit-lib") then
options.useBitLib = true
table.remove(arg, i)
elseif (_768_ == "--metadata") then
options.useMetadata = true
table.remove(arg, i)
elseif (_768_ == "--no-metadata") then
options.useMetadata = false
table.remove(arg, i)
elseif (_768_ == "--no-compiler-sandbox") then
options["compiler-env"] = _G
table.remove(arg, i)
elseif (_768_ == "--raw-errors") then
options.unfriendly = true
table.remove(arg, i)
elseif (_768_ == "--plugin") then
local opts = {env = "_COMPILER", useMetadata = true, ["compiler-env"] = _G}
local plugin = fennel.dofile(table.remove(arg, (i + 1)), opts)
table.insert(options.plugins, 1, plugin)
table.remove(arg, i)
elseif true then
local _ = _768_
if not commands[arg[i]] then
options["ignore-options"] = true
i = (i + 1)
else
end
i = (i + 1)
else
end
end
end
local searcher_opts = {}
if not options["no-searcher"] then
for k, v in pairs(options) do
searcher_opts[k] = v
end
table.insert((package.loaders or package.searchers), fennel["make-searcher"](searcher_opts))
else
end
local function load_initfile()
local home = (os.getenv("HOME") or "/")
local xdg_config_home = (os.getenv("XDG_CONFIG_HOME") or (home .. "/.config"))
local xdg_initfile = (xdg_config_home .. "/fennel/fennelrc")
local home_initfile = (home .. "/.fennelrc")
local init = io.open(xdg_initfile, "rb")
local init_filename
if init then
init_filename = xdg_initfile
else
init_filename = home_initfile
end
local init0 = (init or io.open(home_initfile, "rb"))
if init0 then
init0:close()
return dosafely(fennel.dofile, init_filename, options, options, fennel)
else
return nil
end
end
local function repl()
local readline_3f = (("dumb" ~= os.getenv("TERM")) and pcall(require, "readline"))
searcher_opts.useMetadata = (false ~= options.useMetadata)
if (false ~= options.fennelrc) then
options["fennelrc"] = load_initfile
else
end
print(("Welcome to " .. fennel["runtime-version"]() .. "!"))
print("Use ,help to see available commands.")
if (not readline_3f and ("dumb" ~= os.getenv("TERM"))) then
print("Try installing readline via luarocks for a better repl experience.")
else
end
return fennel.repl(options)
end
local function eval(form)
local _778_
if (form == "-") then
_778_ = (io.stdin):read("*a")
else
_778_ = form
end
return print(dosafely(fennel.eval, _778_, options))
end
local function compile(files)
for _, filename in ipairs(files) do
options.filename = filename
local f
if (filename == "-") then
f = io.stdin
else
f = assert(io.open(filename, "rb"))
end
do
local _781_, _782_ = nil, nil
local function _783_()
return fennel["compile-string"](f:read("*a"), options)
end
_781_, _782_ = xpcall(_783_, fennel.traceback)
if ((_781_ == true) and (nil ~= _782_)) then
local val = _782_
print(val)
elseif (true and (nil ~= _782_)) then
local _0 = _781_
local msg = _782_
do end (io.stderr):write((msg .. "\n"))
os.exit(1)
else
end
end
f:close()
end
return nil
end
local _785_ = arg
local function _786_(...)
return (0 == #arg)
end
if ((_G.type(_785_) == "table") and _786_(...)) then
return repl()
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--repl")) then
return repl()
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--compile")) then
local files = {select(2, (table.unpack or _G.unpack)(_785_))}
return compile(files)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "-c")) then
local files = {select(2, (table.unpack or _G.unpack)(_785_))}
return compile(files)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--compile-binary") and (nil ~= (_785_)[2]) and (nil ~= (_785_)[3]) and (nil ~= (_785_)[4]) and (nil ~= (_785_)[5])) then
local filename = (_785_)[2]
local out = (_785_)[3]
local static_lua = (_785_)[4]
local lua_include_dir = (_785_)[5]
local args = {select(6, (table.unpack or _G.unpack)(_785_))}
local bin = require("fennel.binary")
options.filename = filename
options.requireAsInclude = true
return bin.compile(filename, out, static_lua, lua_include_dir, options, args)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--compile-binary")) then
local cmd = (arg[0] or "fennel")
return print(((require("fennel.binary")).help):format(cmd, cmd, cmd))
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--eval") and (nil ~= (_785_)[2])) then
local form = (_785_)[2]
return eval(form)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "-e") and (nil ~= (_785_)[2])) then
local form = (_785_)[2]
return eval(form)
else
local function _814_(...)
local a = (_785_)[1]
return ((a == "-v") or (a == "--version"))
end
if (((_G.type(_785_) == "table") and (nil ~= (_785_)[1])) and _814_(...)) then
local a = (_785_)[1]
return print(fennel["runtime-version"]())
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "--help")) then
return print(help)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "-h")) then
return print(help)
elseif ((_G.type(_785_) == "table") and ((_785_)[1] == "-")) then
local args = {select(2, (table.unpack or _G.unpack)(_785_))}
return dosafely(fennel.eval, (io.stdin):read("*a"))
elseif ((_G.type(_785_) == "table") and (nil ~= (_785_)[1])) then
local filename = (_785_)[1]
local args = {select(2, (table.unpack or _G.unpack)(_785_))}
arg[-2] = arg[-1]
arg[-1] = arg[0]
arg[0] = table.remove(arg, 1)
return dosafely(fennel.dofile, filename, options, unpack(args))
else
return nil
end
end
return mod

View File

@ -4,11 +4,14 @@ literate.lua
Code under GPLv3 <https://www.gnu.org/licenses/gpl-3.0.en.html>
]]
-- Gets source root directory and Fennel path
-- This will allow to use Lisp inside Lua
-- Initial setup
-- 1. Gets 'src' dir path
-- 2. Enables Fennel for Lisp-Lua embeded compatibility
-- Cfr. https://fennel-lang.org
local src_root = pandoc.path.directory(PANDOC_SCRIPT_FILE)
local fennel = pandoc.path.join({src_root, "fennel"})
local fennel_lua = pandoc.path.join({src_root, "fennel.lua"})
package.path = package.path .. ";" .. fennel_lua
local fennel = require("fennel")
--[[
-- Lua LPeg shortcuts
@ -38,16 +41,19 @@ G = P{
-- Evals Lisp code
-- @param code string: code to evaluate
-- @return table: code evaluated as a table of lines
-- @return table: evaluation result as {bool, string, string, string}
local function eval(code)
local res = {}
local cmd = fennel .. " -e '" .. code .. "' 2>&1"
local handle = io.popen(cmd)
for line in handle:lines() do
table.insert(res, line)
is_passed, out = pcall (
function () return fennel.eval(code) end,
function (e) return e end
)
lua = ""
out = tostring(out)
preview = out:gsub("\n.*", "")
if is_passed then
lua = fennel.compileString(code)
end
handle:close()
return res
return {is_passed = is_passed, preview = preview, out = out, lua = lua}
end
return {
@ -57,9 +63,9 @@ return {
local raw = block.text
print("⚙️ ", raw)
local res = eval(raw)
print("", "=>", res[1])
print("", res["is_passed"], "", res["preview"])
if block.classes:includes("replace") then
return pandoc.CodeBlock(table.concat(res, "\n"), {code=raw})
return pandoc.CodeBlock(res["out"], {code=raw})
end
end
end,

View File

@ -7,7 +7,7 @@ Evals:
(+ 7 8 9)
#+end_src
Fails:
Doesn't eval:
#+begin_src eval replace
(+ 7 8 9)