Fennel is now embeded
This commit is contained in:
parent
a36006cee2
commit
ab643376b1
|
@ -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*
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -7,7 +7,7 @@ Evals:
|
|||
(+ 7 8 9)
|
||||
#+end_src
|
||||
|
||||
Fails:
|
||||
Doesn't eval:
|
||||
|
||||
#+begin_src eval replace
|
||||
(+ 7 8 9)
|
||||
|
|
Loading…
Reference in New Issue