diff --git a/fennel b/fennel index d7f3dd9..c3c8d46 100755 --- a/fennel +++ b/fennel @@ -1,28 +1,39 @@ #!/usr/bin/env lua +-- SPDX-License-Identifier: MIT +-- SPDX-FileCopyrightText: Calvin Rose and contributors package.preload["fennel.binary"] = package.preload["fennel.binary"] or function(...) local fennel = require("fennel") - local _770_ = require("fennel.utils") - local copy = _770_["copy"] - local warn = _770_["warn"] + local _782_ = require("fennel.utils") + local copy = _782_["copy"] + local warn = _782_["warn"] 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 _771_0 = os.execute(cmd) - if (_771_0 == 0) then + local _783_0 = os.execute(cmd) + if (_783_0 == 0) then return true - elseif (_771_0 == true) then + elseif (_783_0 == true) then return true 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))) + local _785_ + do + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for character in characters:gmatch(".") do + local val_19_ = ("0x%02x"):format(string.byte(character)) + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + _785_ = tbl_17_ end - return table.concat(hex, ", ") + return table.concat(_785_, ", ") end local c_shim = "#ifdef __cplusplus\nextern \"C\" {\n#endif\n#include \n#include \n#include \n#ifdef __cplusplus\n}\n#endif\n#include \n#include \n#include \n#include \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) @@ -39,13 +50,13 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( local function module_name(open, rename, used_renames) local require_name = nil do - local _774_0 = rename[open] - if (nil ~= _774_0) then - local renamed = _774_0 + local _788_0 = rename[open] + if (nil ~= _788_0) then + local renamed = _788_0 used_renames[open] = true require_name = renamed else - local _ = _774_0 + local _ = _788_0 require_name = open end end @@ -84,14 +95,14 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( local dotpath = filename:gsub("^%.%/", ""):gsub("[\\/]", ".") local dotpath_noextension = (dotpath:match("(.+)%.") or dotpath) local fennel_loader = nil - local _778_ + local _792_ do - _778_ = "(do (local bundle_2_ ...) (fn loader_3_ [name_4_] (match (or (. bundle_2_ name_4_) (. bundle_2_ (.. name_4_ \".init\"))) (mod_5_ ? (= \"function\" (type mod_5_))) mod_5_ (mod_5_ ? (= \"string\" (type mod_5_))) (assert (if (= _VERSION \"Lua 5.1\") (loadstring mod_5_ name_4_) (load mod_5_ name_4_))) nil (values nil (: \"\n\\tmodule '%%s' not found in fennel bundle\" \"format\" name_4_)))) (table.insert (or package.loaders package.searchers) 2 loader_3_) ((assert (loader_3_ \"%s\")) ((or unpack table.unpack) arg)))" + _792_ = "(do (local bundle_2_ ...) (fn loader_3_ [name_4_] (match (or (. bundle_2_ name_4_) (. bundle_2_ (.. name_4_ \".init\"))) (mod_5_ ? (= \"function\" (type mod_5_))) mod_5_ (mod_5_ ? (= \"string\" (type mod_5_))) (assert (if (= _VERSION \"Lua 5.1\") (loadstring mod_5_ name_4_) (load mod_5_ name_4_))) nil (values nil (: \"\n\\tmodule '%%s' not found in fennel bundle\" \"format\" name_4_)))) (table.insert (or package.loaders package.searchers) 2 loader_3_) ((assert (loader_3_ \"%s\")) ((or unpack table.unpack) arg)))" end - fennel_loader = _778_:format(dotpath_noextension) + fennel_loader = _792_:format(dotpath_noextension) local lua_loader = fennel["compile-string"](fennel_loader) - local _779_ = options - local rename_modules = _779_["rename-modules"] + local _793_ = options + local rename_modules = _793_["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) @@ -104,28 +115,28 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( 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 _781_ + local _795_ do - local _780_0 = shellout((cc .. " -dumpmachine")) - if (nil ~= _780_0) then - _781_ = _780_0:match("mingw") + local _794_0 = shellout((cc .. " -dumpmachine")) + if (nil ~= _794_0) then + _795_ = _794_0:match("mingw") else - _781_ = _780_0 + _795_ = _794_0 end end - if _781_ then + if _795_ then rdynamic, bin_extension, ldl_3f = "", ".exe", false else rdynamic, bin_extension, ldl_3f = "-rdynamic", "", true end local compile_command = nil - local _784_ + local _798_ if ldl_3f then - _784_ = "-ldl" + _798_ = "-ldl" else - _784_ = "" + _798_ = "" end - compile_command = {cc, "-Os", lua_c_path, table.concat(native, " "), static_lua, rdynamic, "-lm", _784_, "-o", (executable_name .. bin_extension), "-I", lua_include_dir, os.getenv("CC_OPTS")} + compile_command = {cc, "-Os", lua_c_path, table.concat(native, " "), static_lua, rdynamic, "-lm", _798_, "-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, " ")) end @@ -143,17 +154,17 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( if (version_extension and (version_extension ~= "") and not version_extension:match("%.%d+")) then return false else - local _789_0 = extension - if (_789_0 == "a") then + local _803_0 = extension + if (_803_0 == "a") then return path - elseif (_789_0 == "o") then + elseif (_803_0 == "o") then return path - elseif (_789_0 == "so") then + elseif (_803_0 == "so") then return path - elseif (_789_0 == "dylib") then + elseif (_803_0 == "dylib") then return path else - local _ = _789_0 + local _ = _803_0 return false end end @@ -185,10 +196,10 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( return native end local function compile(filename, executable_name, static_lua, lua_include_dir, options, args) - local _796_ = extract_native_args(args) - local libraries = _796_["libraries"] - local modules = _796_["modules"] - local rename_modules = _796_["rename-modules"] + local _810_ = extract_native_args(args) + local libraries = _810_["libraries"] + local modules = _810_["modules"] + local rename_modules = _810_["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) @@ -204,15 +215,16 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local specials = require("fennel.specials") local view = require("fennel.view") local unpack = (table.unpack or _G.unpack) - local function default_read_chunk(parser_state) - local function _607_() - if (0 < parser_state["stack-size"]) then - return ".." - else - return ">> " - end + local depth = 0 + local function prompt_for(top_3f) + if top_3f then + return (string.rep(">", (depth + 1)) .. " ") + else + return (string.rep(".", (depth + 1)) .. " ") end - io.write(_607_()) + end + local function default_read_chunk(parser_state) + io.write(prompt_for((0 == parser_state["stack-size"]))) io.flush() local input = io.read() return (input and (input .. "\n")) @@ -222,18 +234,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return io.write("\n") end local function default_on_error(errtype, err, lua_source) - local function _609_() - local _608_0 = errtype - if (_608_0 == "Lua Compile") then + local function _613_() + local _612_0 = errtype + if (_612_0 == "Lua Compile") then return ("Bad code generated - likely a bug with the compiler:\n" .. "--- Generated Lua Start ---\n" .. lua_source .. "--- Generated Lua End ---\n") - elseif (_608_0 == "Runtime") then + elseif (_612_0 == "Runtime") then return (compiler.traceback(tostring(err), 4) .. "\n") else - local _ = _608_0 + local _ = _612_0 return ("%s error: %s\n"):format(errtype, tostring(err)) end end - return io.write(_609_()) + return io.write(_613_()) end local function splice_save_locals(env, lua_source, scope) local saves = nil @@ -241,7 +253,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for name in pairs(env.___replLocals___) do - local val_19_ = ("local %s = ___replLocals___['%s']"):format((scope.manglings[name] or name), name) + local val_19_ = ("local %s = ___replLocals___[%q]"):format((scope.manglings[name] or name), name) if (nil ~= val_19_) then i_18_ = (i_18_ + 1) tbl_17_[i_18_] = val_19_ @@ -256,7 +268,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) for raw, name in pairs(scope.manglings) do local val_19_ = nil if not scope.gensyms[name] then - val_19_ = ("___replLocals___['%s'] = %s"):format(raw, name) + val_19_ = ("___replLocals___[%q] = %s"):format(raw, name) else val_19_ = nil end @@ -273,25 +285,25 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) else gap = " " end - local function _615_() + local function _619_() if next(saves) then return (table.concat(saves, " ") .. gap) else return "" end end - local function _618_() - local _616_0, _617_0 = lua_source:match("^(.*)[\n ](return .*)$") - if ((nil ~= _616_0) and (nil ~= _617_0)) then - local body = _616_0 - local _return = _617_0 + local function _622_() + local _620_0, _621_0 = lua_source:match("^(.*)[\n ](return .*)$") + if ((nil ~= _620_0) and (nil ~= _621_0)) then + local body = _620_0 + local _return = _621_0 return (body .. gap .. table.concat(binds, " ") .. gap .. _return) else - local _ = _616_0 + local _ = _620_0 return lua_source end end - return (_615_() .. _618_()) + return (_619_() .. _622_()) end local function completer(env, scope, text) local max_items = 2000 @@ -303,14 +315,14 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local scope_first_3f = ((tbl == env) or (tbl == env.___replLocals___)) local tbl_17_ = matches local i_18_ = #tbl_17_ - local function _620_() + local function _624_() if scope_first_3f then return scope.manglings else return tbl end end - for k, is_mangled in utils.allpairs(_620_()) do + for k, is_mangled in utils.allpairs(_624_()) do if (max_items <= #matches) then break end local val_19_ = nil do @@ -378,7 +390,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return input:match("^%s*,") end local function command_docs() - local _629_ + local _633_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -389,18 +401,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) tbl_17_[i_18_] = val_19_ end end - _629_ = tbl_17_ + _633_ = tbl_17_ end - return table.concat(_629_, "\n") + return table.concat(_633_, "\n") end commands.help = function(_, _0, on_values) - return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,exit - Leave the repl.\n\nUse ,doc something to see descriptions for individual macros and special forms.\n\nFor more information about the language, see https://fennel-lang.org/reference")}) + return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,return FORM - Evaluate FORM and return its value to the REPL's caller.\n ,exit - Leave the repl.\n\nUse ,doc something to see descriptions for individual macros and special forms.\nValues from previous inputs are kept in *1, *2, and *3.\n\nFor more information about the language, see https://fennel-lang.org/reference")}) end do end (compiler.metadata):set(commands.help, "fnl/docstring", "Show this message.") local function reload(module_name, env, on_values, on_error) - local _631_0, _632_0 = pcall(specials["load-code"]("return require(...)", env), module_name) - if ((_631_0 == true) and (nil ~= _632_0)) then - local old = _632_0 + local _635_0, _636_0 = pcall(specials["load-code"]("return require(...)", env), module_name) + if ((_635_0 == true) and (nil ~= _636_0)) then + local old = _636_0 local _ = nil package.loaded[module_name] = nil _ = nil @@ -425,8 +437,8 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) package.loaded[module_name] = old end return on_values({"ok"}) - elseif ((_631_0 == false) and (nil ~= _632_0)) then - local msg = _632_0 + elseif ((_635_0 == false) and (nil ~= _636_0)) then + local msg = _636_0 if msg:match("loop or previous error loading module") then package.loaded[module_name] = nil return reload(module_name, env, on_values, on_error) @@ -434,32 +446,32 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) specials["macro-loaded"][module_name] = nil return nil else - local function _637_() - local _636_0 = msg:gsub("\n.*", "") - return _636_0 + local function _641_() + local _640_0 = msg:gsub("\n.*", "") + return _640_0 end - return on_error("Runtime", _637_()) + return on_error("Runtime", _641_()) end end end local function run_command(read, on_error, f) - local _640_0, _641_0, _642_0 = pcall(read) - if ((_640_0 == true) and (_641_0 == true) and (nil ~= _642_0)) then - local val = _642_0 - local _643_0, _644_0 = pcall(f, val) - if ((_643_0 == false) and (nil ~= _644_0)) then - local msg = _644_0 + local _644_0, _645_0, _646_0 = pcall(read) + if ((_644_0 == true) and (_645_0 == true) and (nil ~= _646_0)) then + local val = _646_0 + local _647_0, _648_0 = pcall(f, val) + if ((_647_0 == false) and (nil ~= _648_0)) then + local msg = _648_0 return on_error("Runtime", msg) end - elseif (_640_0 == false) then + elseif (_644_0 == false) then return on_error("Parse", "Couldn't parse input.") end end commands.reload = function(env, read, on_values, on_error) - local function _647_(_241) + local function _651_(_241) return reload(tostring(_241), env, on_values, on_error) end - return run_command(read, on_error, _647_) + return run_command(read, on_error, _651_) end do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.") commands.reset = function(env, _, on_values) @@ -468,28 +480,28 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end do end (compiler.metadata):set(commands.reset, "fnl/docstring", "Erase all repl-local scope.") commands.complete = function(env, read, on_values, on_error, scope, chars) - local function _648_() + local function _652_() return on_values(completer(env, scope, table.concat(chars):gsub(",complete +", ""):sub(1, -2))) end - return run_command(read, on_error, _648_) + return run_command(read, on_error, _652_) end do end (compiler.metadata):set(commands.complete, "fnl/docstring", "Print all possible completions for a given input symbol.") local function apropos_2a(pattern, tbl, prefix, seen, names) for name, subtbl in pairs(tbl) do if (("string" == type(name)) and (package ~= subtbl)) then - local _649_0 = type(subtbl) - if (_649_0 == "function") then + local _653_0 = type(subtbl) + if (_653_0 == "function") then if ((prefix .. name)):match(pattern) then table.insert(names, (prefix .. name)) end - elseif (_649_0 == "table") then + elseif (_653_0 == "table") then if not seen[subtbl] then - local _651_ + local _655_ do seen[subtbl] = true - _651_ = seen + _655_ = seen end - apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _651_, names) + apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _655_, names) end end end @@ -510,10 +522,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return tbl_17_ end commands.apropos = function(_env, read, on_values, on_error, _scope) - local function _656_(_241) + local function _660_(_241) return on_values(apropos(tostring(_241))) end - return run_command(read, on_error, _656_) + return run_command(read, on_error, _660_) end do end (compiler.metadata):set(commands.apropos, "fnl/docstring", "Print all functions matching a pattern in all loaded modules.") local function apropos_follow_path(path) @@ -533,12 +545,12 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local tgt = package.loaded for _, path0 in ipairs(paths) do if (nil == tgt) then break end - local _659_ + local _663_ do - local _658_0 = path0:gsub("%/", ".") - _659_ = _658_0 + local _662_0 = path0:gsub("%/", ".") + _663_ = _662_0 end - tgt = tgt[_659_] + tgt = tgt[_663_] end return tgt end @@ -550,9 +562,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) do local tgt = apropos_follow_path(path) if ("function" == type(tgt)) then - local _660_0 = (compiler.metadata):get(tgt, "fnl/docstring") - if (nil ~= _660_0) then - local docstr = _660_0 + local _664_0 = (compiler.metadata):get(tgt, "fnl/docstring") + if (nil ~= _664_0) then + local docstr = _664_0 val_19_ = (docstr:match(pattern) and path) else val_19_ = nil @@ -569,125 +581,125 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return tbl_17_ end commands["apropos-doc"] = function(_env, read, on_values, on_error, _scope) - local function _664_(_241) + local function _668_(_241) return on_values(apropos_doc(tostring(_241))) end - return run_command(read, on_error, _664_) + return run_command(read, on_error, _668_) end do end (compiler.metadata):set(commands["apropos-doc"], "fnl/docstring", "Print all functions that match the pattern in their docs") local function apropos_show_docs(on_values, pattern) for _, path in ipairs(apropos(pattern)) do local tgt = apropos_follow_path(path) if (("function" == type(tgt)) and (compiler.metadata):get(tgt, "fnl/docstring")) then - on_values(specials.doc(tgt, path)) - on_values() + on_values({specials.doc(tgt, path)}) + on_values({}) end end return nil end commands["apropos-show-docs"] = function(_env, read, on_values, on_error) - local function _666_(_241) + local function _670_(_241) return apropos_show_docs(on_values, tostring(_241)) end - return run_command(read, on_error, _666_) + return run_command(read, on_error, _670_) end do end (compiler.metadata):set(commands["apropos-show-docs"], "fnl/docstring", "Print all documentations matching a pattern in function name") - local function resolve(identifier, _667_0, scope) - local _668_ = _667_0 - local env = _668_ - local ___replLocals___ = _668_["___replLocals___"] + local function resolve(identifier, _671_0, scope) + local _672_ = _671_0 + local env = _672_ + local ___replLocals___ = _672_["___replLocals___"] local e = nil - local function _669_(_241, _242) + local function _673_(_241, _242) return (___replLocals___[scope.unmanglings[_242]] or env[_242]) end - e = setmetatable({}, {__index = _669_}) - local function _670_(...) - local _671_0, _672_0 = ... - if ((_671_0 == true) and (nil ~= _672_0)) then - local code = _672_0 - local function _673_(...) - local _674_0, _675_0 = ... - if ((_674_0 == true) and (nil ~= _675_0)) then - local val = _675_0 + e = setmetatable({}, {__index = _673_}) + local function _674_(...) + local _675_0, _676_0 = ... + if ((_675_0 == true) and (nil ~= _676_0)) then + local code = _676_0 + local function _677_(...) + local _678_0, _679_0 = ... + if ((_678_0 == true) and (nil ~= _679_0)) then + local val = _679_0 return val else - local _ = _674_0 + local _ = _678_0 return nil end end - return _673_(pcall(specials["load-code"](code, e))) + return _677_(pcall(specials["load-code"](code, e))) else - local _ = _671_0 + local _ = _675_0 return nil end end - return _670_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) + return _674_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) end commands.find = function(env, read, on_values, on_error, scope) - local function _678_(_241) - local _679_0 = nil + local function _682_(_241) + local _683_0 = nil do - local _680_0 = utils["sym?"](_241) - if (nil ~= _680_0) then - local _681_0 = resolve(_680_0, env, scope) - if (nil ~= _681_0) then - _679_0 = debug.getinfo(_681_0) + local _684_0 = utils["sym?"](_241) + if (nil ~= _684_0) then + local _685_0 = resolve(_684_0, env, scope) + if (nil ~= _685_0) then + _683_0 = debug.getinfo(_685_0) else - _679_0 = _681_0 + _683_0 = _685_0 end else - _679_0 = _680_0 + _683_0 = _684_0 end end - if ((_G.type(_679_0) == "table") and (nil ~= _679_0.linedefined) and (nil ~= _679_0.short_src) and (nil ~= _679_0.source) and (_679_0.what == "Lua")) then - local line = _679_0.linedefined - local src = _679_0.short_src - local source = _679_0.source + if ((_G.type(_683_0) == "table") and (nil ~= _683_0.linedefined) and (nil ~= _683_0.short_src) and (nil ~= _683_0.source) and (_683_0.what == "Lua")) then + local line = _683_0.linedefined + local src = _683_0.short_src + local source = _683_0.source local fnlsrc = nil do - local _684_0 = compiler.sourcemap - if (nil ~= _684_0) then - _684_0 = _684_0[source] + local _688_0 = compiler.sourcemap + if (nil ~= _688_0) then + _688_0 = _688_0[source] end - if (nil ~= _684_0) then - _684_0 = _684_0[line] + if (nil ~= _688_0) then + _688_0 = _688_0[line] end - if (nil ~= _684_0) then - _684_0 = _684_0[2] + if (nil ~= _688_0) then + _688_0 = _688_0[2] end - fnlsrc = _684_0 + fnlsrc = _688_0 end return on_values({string.format("%s:%s", src, (fnlsrc or line))}) - elseif (_679_0 == nil) then + elseif (_683_0 == nil) then return on_error("Repl", "Unknown value") else - local _ = _679_0 + local _ = _683_0 return on_error("Repl", "No source info") end end - return run_command(read, on_error, _678_) + return run_command(read, on_error, _682_) end do end (compiler.metadata):set(commands.find, "fnl/docstring", "Print the filename and line number for a given function") commands.doc = function(env, read, on_values, on_error, scope) - local function _689_(_241) + local function _693_(_241) local name = tostring(_241) local path = (utils["multi-sym?"](name) or {name}) local ok_3f, target = nil, nil - local function _690_() + local function _694_() return (utils["get-in"](scope.specials, path) or utils["get-in"](scope.macros, path) or resolve(name, env, scope)) end - ok_3f, target = pcall(_690_) + ok_3f, target = pcall(_694_) if ok_3f then return on_values({specials.doc(target, name)}) else return on_error("Repl", ("Could not find " .. name .. " for docs.")) end end - return run_command(read, on_error, _689_) + return run_command(read, on_error, _693_) end do end (compiler.metadata):set(commands.doc, "fnl/docstring", "Print the docstring and arglist for a function, macro, or special form.") commands.compile = function(env, read, on_values, on_error, scope) - local function _692_(_241) + local function _696_(_241) local allowedGlobals = specials["current-global-names"](env) local ok_3f, result = pcall(compiler.compile, _241, {allowedGlobals = allowedGlobals, env = env, scope = scope}) if ok_3f then @@ -696,15 +708,15 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return on_error("Repl", ("Error compiling expression: " .. result)) end end - return run_command(read, on_error, _692_) + return run_command(read, on_error, _696_) end do end (compiler.metadata):set(commands.compile, "fnl/docstring", "compiles the expression into lua and prints the result.") local function load_plugin_commands(plugins) for i = #(plugins or {}), 1, -1 do for name, f in pairs(plugins[i]) do - local _694_0 = name:match("^repl%-command%-(.*)") - if (nil ~= _694_0) then - local cmd_name = _694_0 + local _698_0 = name:match("^repl%-command%-(.*)") + if (nil ~= _698_0) then + local cmd_name = _698_0 commands[cmd_name] = f end end @@ -714,19 +726,19 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local function run_command_loop(input, read, loop, env, on_values, on_error, scope, chars) local command_name = input:match(",([^%s/]+)") do - local _696_0 = commands[command_name] - if (nil ~= _696_0) then - local command = _696_0 + local _700_0 = commands[command_name] + if (nil ~= _700_0) then + local command = _700_0 command(env, read, on_values, on_error, scope, chars) else - local _ = _696_0 - if ("exit" ~= command_name) then + local _ = _700_0 + if ((command_name ~= "exit") and (command_name ~= "return")) then on_values({"Unknown command", command_name}) end end end if ("exit" ~= command_name) then - return loop() + return loop((command_name == "return")) end end local function try_readline_21(opts, ok, readline) @@ -769,9 +781,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end local function repl(_3foptions) local old_root_options = utils.root.options - local _705_ = utils.copy(_3foptions) - local opts = _705_ - local _3ffennelrc = _705_["fennelrc"] + local _709_ = utils.copy(_3foptions) + local opts = _709_ + local _3ffennelrc = _709_["fennelrc"] local _ = nil opts.fennelrc = nil _ = nil @@ -786,35 +798,42 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local callbacks = {env = env, onError = (opts.onError or default_on_error), onValues = (opts.onValues or default_on_values), pp = (opts.pp or view), readChunk = (opts.readChunk or default_read_chunk)} local save_locals_3f = (opts.saveLocals ~= false) local byte_stream, clear_stream = nil, nil - local function _707_(_241) + local function _711_(_241) return callbacks.readChunk(_241) end - byte_stream, clear_stream = parser.granulate(_707_) + byte_stream, clear_stream = parser.granulate(_711_) local chars = {} local read, reset = nil, nil - local function _708_(parser_state) + local function _712_(parser_state) local b = byte_stream(parser_state) if b then table.insert(chars, string.char(b)) end return b end - read, reset = parser.parser(_708_) + read, reset = parser.parser(_712_) + depth = (depth + 1) + if opts.message then + callbacks.onValues({opts.message}) + end env.___repl___ = callbacks opts.env, opts.scope = env, compiler["make-scope"]() opts.useMetadata = (opts.useMetadata ~= false) if (opts.allowedGlobals == nil) then opts.allowedGlobals = specials["current-global-names"](env) end + if opts.init then + opts.init(opts, depth) + end if opts.registerCompleter then - local function _712_() - local _711_0 = opts.scope - local function _713_(...) - return completer(env, _711_0, ...) + local function _718_() + local _717_0 = opts.scope + local function _719_(...) + return completer(env, _717_0, ...) end - return _713_ + return _719_ end - opts.registerCompleter(_712_()) + opts.registerCompleter(_718_()) end load_plugin_commands(opts.plugins) if save_locals_3f then @@ -835,12 +854,21 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return callbacks.onValues(out) end - local function loop() + local function save_value(...) + env.___replLocals___["*3"] = env.___replLocals___["*2"] + env.___replLocals___["*2"] = env.___replLocals___["*1"] + env.___replLocals___["*1"] = ... + return ... + end + opts.scope.manglings["*1"], opts.scope.unmanglings._1 = "_1", "*1" + opts.scope.manglings["*2"], opts.scope.unmanglings._2 = "_2", "*2" + opts.scope.manglings["*3"], opts.scope.unmanglings._3 = "_3", "*3" + local function loop(exit_next_3f) for k in pairs(chars) do chars[k] = nil end reset() - local ok, parser_not_eof_3f, x = pcall(read) + local ok, parser_not_eof_3f, form = pcall(read) local src_string = table.concat(chars) local readline_not_eof_3f = (not readline or (src_string ~= "(null)")) local not_eof_3f = (readline_not_eof_3f and parser_not_eof_3f) @@ -852,52 +880,66 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return run_command_loop(src_string, read, loop, env, callbacks.onValues, callbacks.onError, opts.scope, chars) else if not_eof_3f then - do - local _717_0, _718_0 = nil, nil - local function _719_() - opts["source"] = src_string - return opts - end - _717_0, _718_0 = pcall(compiler.compile, x, _719_()) - if ((_717_0 == false) and (nil ~= _718_0)) then - local msg = _718_0 + local function _723_(...) + local _724_0, _725_0 = ... + if ((_724_0 == true) and (nil ~= _725_0)) then + local src = _725_0 + local function _726_(...) + local _727_0, _728_0 = ... + if ((_727_0 == true) and (nil ~= _728_0)) then + local chunk = _728_0 + local function _729_() + return print_values(save_value(chunk())) + end + local function _730_(...) + return callbacks.onError("Runtime", ...) + end + return xpcall(_729_, _730_) + elseif ((_727_0 == false) and (nil ~= _728_0)) then + local msg = _728_0 + clear_stream() + return callbacks.onError("Compile", msg) + end + end + local function _733_(...) + local src0 = nil + if save_locals_3f then + src0 = splice_save_locals(env, src, opts.scope) + else + src0 = src + end + return pcall(specials["load-code"], src0, env) + end + return _726_(_733_(...)) + elseif ((_724_0 == false) and (nil ~= _725_0)) then + local msg = _725_0 clear_stream() - callbacks.onError("Compile", msg) - elseif ((_717_0 == true) and (nil ~= _718_0)) then - local src = _718_0 - local src0 = nil - if save_locals_3f then - src0 = splice_save_locals(env, src, opts.scope) - else - src0 = src - end - local _721_0, _722_0 = pcall(specials["load-code"], src0, env) - if ((_721_0 == false) and (nil ~= _722_0)) then - local msg = _722_0 - clear_stream() - callbacks.onError("Lua Compile", msg, src0) - elseif (true and (nil ~= _722_0)) then - local _1 = _721_0 - local chunk = _722_0 - local function _723_() - return print_values(chunk()) - end - local function _724_(...) - return callbacks.onError("Runtime", ...) - end - xpcall(_723_, _724_) - end + return callbacks.onError("Compile", msg) end end + local function _735_() + opts["source"] = src_string + return opts + end + _723_(pcall(compiler.compile, form, _735_())) utils.root.options = old_root_options - return loop() + if exit_next_3f then + return env.___replLocals___["*1"] + else + return loop() + end end end end - loop() + local value = loop() + depth = (depth - 1) if readline then - return readline.save_history() + readline.save_history() end + if opts.exit then + opts.exit(opts, depth) + end + return value end return repl end @@ -909,14 +951,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local unpack = (table.unpack or _G.unpack) local SPECIALS = compiler.scopes.global.specials local function wrap_env(env) - local function _416_(_, key) + local function _418_(_, key) if utils["string?"](key) then return env[compiler["global-unmangling"](key)] else return env[key] end end - local function _418_(_, key, value) + local function _420_(_, key, value) if utils["string?"](key) then env[compiler["global-unmangling"](key)] = value return nil @@ -925,26 +967,26 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return nil end end - local function _420_() + local function _422_() local function putenv(k, v) - local _421_ + local _423_ if utils["string?"](k) then - _421_ = compiler["global-unmangling"](k) + _423_ = compiler["global-unmangling"](k) else - _421_ = k + _423_ = k end - return _421_, v + return _423_, v end return next, utils.kvmap(env, putenv), nil end - return setmetatable({}, {__index = _416_, __newindex = _418_, __pairs = _420_}) + return setmetatable({}, {__index = _418_, __newindex = _420_, __pairs = _422_}) end local function current_global_names(_3fenv) local mt = nil do - local _423_0 = getmetatable(_3fenv) - if ((_G.type(_423_0) == "table") and (nil ~= _423_0.__pairs)) then - local mtpairs = _423_0.__pairs + local _425_0 = getmetatable(_3fenv) + if ((_G.type(_425_0) == "table") and (nil ~= _425_0.__pairs)) then + local mtpairs = _425_0.__pairs local tbl_14_ = {} for k, v in mtpairs(_3fenv) do local k_15_, v_16_ = k, v @@ -953,7 +995,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end mt = tbl_14_ - elseif (_423_0 == nil) then + elseif (_425_0 == nil) then mt = (_3fenv or _G) else mt = nil @@ -963,15 +1005,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function load_code(code, _3fenv, _3ffilename) local env = (_3fenv or rawget(_G, "_ENV") or _G) - local _426_0, _427_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") - if ((nil ~= _426_0) and (nil ~= _427_0)) then - local setfenv = _426_0 - local loadstring = _427_0 + local _428_0, _429_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") + if ((nil ~= _428_0) and (nil ~= _429_0)) then + local setfenv = _428_0 + local loadstring = _429_0 local f = assert(loadstring(code, _3ffilename)) setfenv(f, env) return f else - local _ = _426_0 + local _ = _428_0 return assert(load(code, _3ffilename, "t", env)) end end @@ -983,13 +1025,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local mt = getmetatable(tgt) if ((type(tgt) == "function") or ((type(mt) == "table") and (type(mt.__call) == "function"))) then local arglist = table.concat(((compiler.metadata):get(tgt, "fnl/arglist") or {"#"}), " ") - local _429_ + local _431_ if (0 < #arglist) then - _429_ = " " + _431_ = " " else - _429_ = "" + _431_ = "" end - return string.format("(%s%s%s)\n %s", name, _429_, arglist, docstring) + return string.format("(%s%s%s)\n %s", name, _431_, arglist, docstring) else return string.format("%s\n %s", name, docstring) end @@ -1016,16 +1058,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local retexprs = {returned = true} utils.hook("customhook-early-do", ast, sub_scope) local function compile_body(outer_target, outer_tail, outer_retexprs) - if (len < start) then - compiler.compile1(nil, sub_scope, chunk, {tail = outer_tail, target = outer_target}) - else - for i = start, len do - local subopts = {nval = (((i ~= len) and 0) or opts.nval), tail = (((i == len) and outer_tail) or nil), target = (((i == len) and outer_target) or nil)} - local _ = utils["propagate-options"](opts, subopts) - local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts) - if (i ~= len) then - compiler["keep-side-effects"](subexprs, parent, nil, ast[i]) - end + for i = start, len do + local subopts = {nval = (((i ~= len) and 0) or opts.nval), tail = (((i == len) and outer_tail) or nil), target = (((i == len) and outer_target) or nil)} + local _ = utils["propagate-options"](opts, subopts) + local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts) + if (i ~= len) then + compiler["keep-side-effects"](subexprs, parent, nil, ast[i]) end end compiler.emit(parent, chunk, ast) @@ -1103,9 +1141,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local opts = {nval = 1, tail = false} local scope = compiler["make-scope"]() local chunk = {} - local _440_ = compiler.compile1(v, scope, chunk, opts) - local _441_ = _440_[1] - local v0 = _441_[1] + local _441_ = compiler.compile1(v, scope, chunk, opts) + local _442_ = _441_[1] + local v0 = _442_[1] return v0 end local function insert_meta(meta, k, v) @@ -1113,23 +1151,23 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((type(k) == "string"), ("expected string keys in metadata table, got: %s"):format(view(k, view_opts))) compiler.assert(literal_3f(v), ("expected literal value in metadata table, got: %s %s"):format(view(k, view_opts), view(v, view_opts))) table.insert(meta, view(k)) - local function _442_() + local function _443_() if ("string" == type(v)) then return view(v, view_opts) else return compile_value(v) end end - table.insert(meta, _442_()) + table.insert(meta, _443_()) return meta end local function insert_arglist(meta, arg_list) local view_opts = {["escape-newlines?"] = true, ["line-length"] = math.huge, ["one-line?"] = true} table.insert(meta, "\"fnl/arglist\"") - local function _443_(_241) + local function _444_(_241) return view(view(_241, view_opts)) end - table.insert(meta, ("{" .. table.concat(utils.map(arg_list, _443_), ", ") .. "}")) + table.insert(meta, ("{" .. table.concat(utils.map(arg_list, _444_), ", ") .. "}")) return meta end local function set_fn_metadata(f_metadata, parent, fn_name) @@ -1148,13 +1186,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function get_fn_name(ast, scope, fn_name, multi) if (fn_name and (fn_name[1] ~= "nil")) then - local _446_ + local _447_ if not multi then - _446_ = compiler["declare-local"](fn_name, {}, scope, ast) + _447_ = compiler["declare-local"](fn_name, {}, scope, ast) else - _446_ = compiler["symbol-to-expression"](fn_name, scope)[1] + _447_ = compiler["symbol-to-expression"](fn_name, scope)[1] end - return _446_, not multi, 3 + return _447_, not multi, 3 else return nil, true, 2 end @@ -1164,13 +1202,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct for i = (index + 1), #ast do compiler.compile1(ast[i], f_scope, f_chunk, {nval = (((i ~= #ast) and 0) or nil), tail = (i == #ast)}) end - local _449_ + local _450_ if local_3f then - _449_ = "local function %s(%s)" + _450_ = "local function %s(%s)" else - _449_ = "%s = function(%s)" + _450_ = "%s = function(%s)" end - compiler.emit(parent, string.format(_449_, fn_name, table.concat(arg_name_list, ", ")), ast) + compiler.emit(parent, string.format(_450_, fn_name, table.concat(arg_name_list, ", ")), ast) compiler.emit(parent, f_chunk, ast) compiler.emit(parent, "end", ast) set_fn_metadata(f_metadata, parent, fn_name) @@ -1192,7 +1230,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function get_function_metadata(ast, arg_list, index) - local function _452_(_241, _242) + local function _453_(_241, _242) local tbl_14_ = _241 for k, v in pairs(_242) do local k_15_, v_16_ = k, v @@ -1202,18 +1240,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_14_ end - local function _454_(_241, _242) + local function _455_(_241, _242) _241["fnl/docstring"] = _242 return _241 end - return maybe_metadata(ast, utils["kv-table?"], _452_, maybe_metadata(ast, utils["string?"], _454_, {["fnl/arglist"] = arg_list}, index)) + return maybe_metadata(ast, utils["kv-table?"], _453_, maybe_metadata(ast, utils["string?"], _455_, {["fnl/arglist"] = arg_list}, index)) end SPECIALS.fn = function(ast, scope, parent) local f_scope = nil do - local _455_0 = compiler["make-scope"](scope) - _455_0["vararg"] = false - f_scope = _455_0 + local _456_0 = compiler["make-scope"](scope) + _456_0["vararg"] = false + f_scope = _456_0 end local f_chunk = {} local fn_sym = utils["sym?"](ast[2]) @@ -1273,36 +1311,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("fn", {"name?", "args", "docstring?", "..."}, "Function syntax. May optionally include a name and docstring or a metadata table.\nIf a name is provided, the function will be bound in the current scope.\nWhen called with the wrong number of args, excess args will be discarded\nand lacking args will be nil, use lambda for arity-checked functions.", true) SPECIALS.lua = function(ast, _, parent) compiler.assert(((#ast == 2) or (#ast == 3)), "expected 1 or 2 arguments", ast) - local _460_ + local _461_ do - local _459_0 = utils["sym?"](ast[2]) - if (nil ~= _459_0) then - _460_ = tostring(_459_0) + local _460_0 = utils["sym?"](ast[2]) + if (nil ~= _460_0) then + _461_ = tostring(_460_0) else - _460_ = _459_0 + _461_ = _460_0 end end - if ("nil" ~= _460_) then + if ("nil" ~= _461_) then table.insert(parent, {ast = ast, leaf = tostring(ast[2])}) end - local _464_ + local _465_ do - local _463_0 = utils["sym?"](ast[3]) - if (nil ~= _463_0) then - _464_ = tostring(_463_0) + local _464_0 = utils["sym?"](ast[3]) + if (nil ~= _464_0) then + _465_ = tostring(_464_0) else - _464_ = _463_0 + _465_ = _464_0 end end - if ("nil" ~= _464_) then + if ("nil" ~= _465_) then return tostring(ast[3]) end end local function dot(ast, scope, parent) compiler.assert((1 < #ast), "expected table argument", ast) local len = #ast - local _467_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local lhs = _467_[1] + local _468_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local lhs = _468_[1] if (len == 2) then return tostring(lhs) else @@ -1312,8 +1350,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if (utils["string?"](index) and utils["valid-lua-identifier?"](index)) then table.insert(indices, ("." .. index)) else - local _468_ = compiler.compile1(index, scope, parent, {nval = 1}) - local index0 = _468_[1] + local _469_ = compiler.compile1(index, scope, parent, {nval = 1}) + local index0 = _469_[1] table.insert(indices, ("[" .. tostring(index0) .. "]")) end end @@ -1358,7 +1396,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end doc_special("var", {"name", "val"}, "Introduce new mutable local.") local function kv_3f(t) - local _472_ + local _473_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1374,9 +1412,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _472_ = tbl_17_ + _473_ = tbl_17_ end - return _472_[1] + return _473_[1] end SPECIALS.let = function(ast, scope, parent, opts) local bindings = ast[2] @@ -1403,22 +1441,22 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function disambiguate_3f(rootstr, parent) - local function _477_() - local _476_0 = get_prev_line(parent) - if (nil ~= _476_0) then - local prev_line = _476_0 + local function _478_() + local _477_0 = get_prev_line(parent) + if (nil ~= _477_0) then + local prev_line = _477_0 return prev_line:match("%)$") end end - return (rootstr:match("^{") or rootstr:match("^%(") or _477_()) + return (rootstr:match("^{") or rootstr:match("^%(") or _478_()) end SPECIALS.tset = function(ast, scope, parent) compiler.assert((3 < #ast), "expected table, key, and value arguments", ast) local root = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] local keys = {} for i = 3, (#ast - 1) do - local _479_ = compiler.compile1(ast[i], scope, parent, {nval = 1}) - local key = _479_[1] + local _480_ = compiler.compile1(ast[i], scope, parent, {nval = 1}) + local key = _480_[1] table.insert(keys, tostring(key)) end local value = compiler.compile1(ast[#ast], scope, parent, {nval = 1})[1] @@ -1432,7 +1470,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return compiler.emit(parent, fmtstr:format(rootstr, table.concat(keys, "]["), tostring(value)), ast) end doc_special("tset", {"tbl", "key1", "...", "keyN", "val"}, "Set the value of a table field. Can take additional keys to set\nnested values, but all parents must contain an existing table.") - local function calculate_target(scope, opts) + local function calculate_if_target(scope, opts) if not (opts.tail or opts.target or opts.nval) then return "iife", true, nil elseif (opts.nval and (opts.nval ~= 0) and not opts.target) then @@ -1461,7 +1499,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct else local do_scope = compiler["make-scope"](scope) local branches = {} - local wrapper, inner_tail, inner_target, target_exprs = calculate_target(scope, opts) + local wrapper, inner_tail, inner_target, target_exprs = calculate_if_target(scope, opts) local body_opts = {nval = opts.nval, tail = inner_tail, target = inner_target} local function compile_body(i) local chunk = {} @@ -1545,15 +1583,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function compile_until(condition, scope, chunk) if condition then - local _490_ = compiler.compile1(condition, scope, chunk, {nval = 1}) - local condition_lua = _490_[1] + local _491_ = compiler.compile1(condition, scope, chunk, {nval = 1}) + local condition_lua = _491_[1] return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(condition, "expression")) end end SPECIALS.each = function(ast, scope, parent) compiler.assert((3 <= #ast), "expected body expression", ast[1]) compiler.assert(utils["table?"](ast[2]), "expected binding table", ast) - compiler.assert((2 <= #ast[2]), "expected binding and iterator", ast) local binding = setmetatable(utils.copy(ast[2]), getmetatable(ast[2])) local until_condition = remove_until_condition(binding) local iter = table.remove(binding, #binding) @@ -1575,6 +1612,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local vals = compiler.compile1(iter, scope, parent) local val_names = utils.map(vals, tostring) local chunk = {} + compiler.assert(bind_vars[1], "expected binding and iterator", ast) compiler.emit(parent, ("for %s in %s do"):format(table.concat(bind_vars, ", "), table.concat(val_names, ", ")), ast) for raw, args in utils.stablepairs(destructures) do compiler.destructure(args, raw, ast, sub_scope, chunk, {declaration = true, nomulti = true, symtype = "each"}) @@ -1632,10 +1670,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct SPECIALS["for"] = for_2a doc_special("for", {"[index start stop step?]", "..."}, "Numeric loop construct.\nEvaluates body once for each value between start and stop (inclusive).", true) local function native_method_call(ast, _scope, _parent, target, args) - local _494_ = ast - local _ = _494_[1] - local _0 = _494_[2] - local method_string = _494_[3] + local _495_ = ast + local _ = _495_[1] + local _0 = _495_[2] + local method_string = _495_[3] local call_string = nil if ((target.type == "literal") or (target.type == "varg") or (target.type == "expression")) then call_string = "(%s):%s(%s)" @@ -1657,18 +1695,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function method_call(ast, scope, parent) compiler.assert((2 < #ast), "expected at least 2 arguments", ast) - local _496_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local target = _496_[1] + local _497_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local target = _497_[1] local args = {} for i = 4, #ast do local subexprs = nil - local _497_ + local _498_ if (i ~= #ast) then - _497_ = 1 + _498_ = 1 else - _497_ = nil + _498_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _497_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _498_}) utils.map(subexprs, tostring, args) end if (utils["string?"](ast[3]) and utils["valid-lua-identifier?"](ast[3])) then @@ -1683,14 +1721,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special(":", {"tbl", "method-name", "..."}, "Call the named method on tbl with the provided args.\nMethod name doesn't have to be known at compile-time; if it is, use\n(tbl:method-name ...) instead.") SPECIALS.comment = function(ast, _, parent) local c = nil - local _500_ + local _501_ do local tbl_17_ = {} local i_18_ = #tbl_17_ for i, elt in ipairs(ast) do local val_19_ = nil if (i ~= 1) then - val_19_ = view(ast[i], {["one-line?"] = true}) + val_19_ = view(elt, {["one-line?"] = true}) else val_19_ = nil end @@ -1699,9 +1737,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _500_ = tbl_17_ + _501_ = tbl_17_ end - c = table.concat(_500_, " "):gsub("%]%]", "]\\]") + c = table.concat(_501_, " "):gsub("%]%]", "]\\]") return compiler.emit(parent, ("--[[ " .. c .. " ]]"), ast) end doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true) @@ -1722,10 +1760,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local f_scope = nil do - local _505_0 = compiler["make-scope"](scope) - _505_0["vararg"] = false - _505_0["hashfn"] = true - f_scope = _505_0 + local _506_0 = compiler["make-scope"](scope) + _506_0["vararg"] = false + _506_0["hashfn"] = true + f_scope = _506_0 end local f_chunk = {} local name = compiler.gensym(scope) @@ -1766,17 +1804,17 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return utils.expr(name, "sym") end doc_special("hashfn", {"..."}, "Function literal shorthand; args are either $... OR $1, $2, etc.") - local function maybe_short_circuit_protect(ast, i, name, _510_0) - local _511_ = _510_0 - local mac = _511_["macros"] + local function maybe_short_circuit_protect(ast, i, name, _511_0) + local _512_ = _511_0 + local mac = _512_["macros"] local call = (utils["list?"](ast) and tostring(ast[1])) if ((("or" == name) or ("and" == name)) and (1 < i) and (mac[call] or ("set" == call) or ("tset" == call) or ("global" == call))) then - return utils.list(utils.sym("do"), ast) + return utils.list(utils.list(utils.sym("fn"), utils.sequence(utils.varg()), ast)) else return ast end end - local function arithmetic_special(name, zero_arity, unary_prefix, ast, scope, parent) + local function operator_special(name, zero_arity, unary_prefix, ast, scope, parent) local len = #ast local operands = {} local padded_op = (" " .. name .. " ") @@ -1789,15 +1827,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct table.insert(operands, tostring(subexprs[1])) end end - local _514_0 = #operands - if (_514_0 == 0) then - local _515_ + local _515_0 = #operands + if (_515_0 == 0) then + local _516_ do compiler.assert(zero_arity, "Expected more than 0 arguments", ast) - _515_ = zero_arity + _516_ = zero_arity end - return utils.expr(_515_, "literal") - elseif (_514_0 == 1) then + return utils.expr(_516_, "literal") + elseif (_515_0 == 1) then if utils["varg?"](ast[2]) then return compiler.assert(false, "tried to use vararg with operator", ast) elseif unary_prefix then @@ -1806,20 +1844,20 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return operands[1] end else - local _ = _514_0 + local _ = _515_0 return ("(" .. table.concat(operands, padded_op) .. ")") end end local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name) - local _519_ + local _520_ do - local _518_0 = (_3flua_name or name) - local function _520_(...) - return arithmetic_special(_518_0, zero_arity, unary_prefix, ...) + local _519_0 = (_3flua_name or name) + local function _521_(...) + return operator_special(_519_0, zero_arity, unary_prefix, ...) end - _519_ = _520_ + _520_ = _521_ end - SPECIALS[name] = _519_ + SPECIALS[name] = _520_ return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.") end define_arithmetic_special("+", "0") @@ -1831,10 +1869,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct define_arithmetic_special("/", nil, "1") define_arithmetic_special("//", nil, "1") SPECIALS["or"] = function(ast, scope, parent) - return arithmetic_special("or", "false", nil, ast, scope, parent) + return operator_special("or", "false", nil, ast, scope, parent) end SPECIALS["and"] = function(ast, scope, parent) - return arithmetic_special("and", "true", nil, ast, scope, parent) + return operator_special("and", "true", nil, ast, scope, parent) end doc_special("and", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.") doc_special("or", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.") @@ -1848,13 +1886,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local prefixed_lib_name = ("bit." .. lib_name) for i = 2, len do local subexprs = nil - local _521_ + local _522_ if (i ~= len) then - _521_ = 1 + _522_ = 1 else - _521_ = nil + _522_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _521_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _522_}) utils.map(subexprs, tostring, operands) end if (#operands == 1) then @@ -1873,10 +1911,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function define_bitop_special(name, zero_arity, unary_prefix, native) - local function _527_(...) + local function _528_(...) return bitop_special(native, name, zero_arity, unary_prefix, ...) end - SPECIALS[name] = _527_ + SPECIALS[name] = _528_ return nil end define_bitop_special("lshift", nil, "1", "<<") @@ -1891,8 +1929,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("bxor", {"x1", "x2", "..."}, "Bitwise XOR of any number of arguments.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.") SPECIALS.bnot = function(ast, scope, parent) compiler.assert((#ast == 2), "expected one argument", ast) - local _528_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local value = _528_[1] + local _529_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local value = _529_[1] if utils.root.options.useBitLib then return ("bit.bnot(" .. tostring(value) .. ")") else @@ -1901,15 +1939,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end doc_special("bnot", {"x"}, "Bitwise negation; only works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.") doc_special("..", {"a", "b", "..."}, "String concatenation operator; works the same as Lua but accepts more arguments.") - local function native_comparator(op, _530_0, scope, parent) - local _531_ = _530_0 - local _ = _531_[1] - local lhs_ast = _531_[2] - local rhs_ast = _531_[3] - local _532_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) - local lhs = _532_[1] - local _533_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) - local rhs = _533_[1] + local function native_comparator(op, _531_0, scope, parent) + local _532_ = _531_0 + local _ = _532_[1] + local lhs_ast = _532_[2] + local rhs_ast = _532_[3] + local _533_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) + local lhs = _533_[1] + local _534_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) + local rhs = _534_[1] return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs)) end local function idempotent_comparator(op, chain_op, ast, scope, parent) @@ -2022,21 +2060,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local safe_require = nil local function safe_compiler_env() - local _540_ + local _541_ do - local _539_0 = rawget(_G, "utf8") - if (nil ~= _539_0) then - _540_ = utils.copy(_539_0) + local _540_0 = rawget(_G, "utf8") + if (nil ~= _540_0) then + _541_ = utils.copy(_540_0) else - _540_ = _539_0 + _541_ = _540_0 end end - return {_VERSION = _VERSION, assert = assert, bit = rawget(_G, "bit"), error = error, getmetatable = safe_getmetatable, ipairs = ipairs, math = utils.copy(math), next = next, pairs = utils.stablepairs, pcall = pcall, print = print, rawequal = rawequal, rawget = rawget, rawlen = rawget(_G, "rawlen"), rawset = rawset, require = safe_require, select = select, setmetatable = setmetatable, string = utils.copy(string), table = utils.copy(table), tonumber = tonumber, tostring = tostring, type = type, utf8 = _540_, xpcall = xpcall} + return {_VERSION = _VERSION, assert = assert, bit = rawget(_G, "bit"), error = error, getmetatable = safe_getmetatable, ipairs = ipairs, math = utils.copy(math), next = next, pairs = utils.stablepairs, pcall = pcall, print = print, rawequal = rawequal, rawget = rawget, rawlen = rawget(_G, "rawlen"), rawset = rawset, require = safe_require, select = select, setmetatable = setmetatable, string = utils.copy(string), table = utils.copy(table), tonumber = tonumber, tostring = tostring, type = type, utf8 = _541_, xpcall = xpcall} end local function combined_mt_pairs(env) local combined = {} - local _542_ = getmetatable(env) - local __index = _542_["__index"] + local _543_ = getmetatable(env) + local __index = _543_["__index"] if ("table" == type(__index)) then for k, v in pairs(__index) do combined[k] = v @@ -2050,40 +2088,40 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function make_compiler_env(ast, scope, parent, _3fopts) local provided = nil do - local _544_0 = (_3fopts or utils.root.options) - if ((_G.type(_544_0) == "table") and (_544_0["compiler-env"] == "strict")) then + local _545_0 = (_3fopts or utils.root.options) + if ((_G.type(_545_0) == "table") and (_545_0["compiler-env"] == "strict")) then provided = safe_compiler_env() - elseif ((_G.type(_544_0) == "table") and (nil ~= _544_0.compilerEnv)) then - local compilerEnv = _544_0.compilerEnv + elseif ((_G.type(_545_0) == "table") and (nil ~= _545_0.compilerEnv)) then + local compilerEnv = _545_0.compilerEnv provided = compilerEnv - elseif ((_G.type(_544_0) == "table") and (nil ~= _544_0["compiler-env"])) then - local compiler_env = _544_0["compiler-env"] + elseif ((_G.type(_545_0) == "table") and (nil ~= _545_0["compiler-env"])) then + local compiler_env = _545_0["compiler-env"] provided = compiler_env else - local _ = _544_0 - provided = safe_compiler_env(false) + local _ = _545_0 + provided = safe_compiler_env() end end local env = nil - local function _546_() + local function _547_() return compiler.scopes.macro end - local function _547_(symbol) + local function _548_(symbol) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.scopes.macro.manglings[tostring(symbol)] end - local function _548_(base) + local function _549_(base) return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base)) end - local function _549_(form) + local function _550_(form) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.macroexpand(form, compiler.scopes.macro) end - env = {["assert-compile"] = compiler.assert, ["ast-source"] = utils["ast-source"], ["comment?"] = utils["comment?"], ["get-scope"] = _546_, ["in-scope?"] = _547_, ["list?"] = utils["list?"], ["macro-loaded"] = macro_loaded, ["multi-sym?"] = utils["multi-sym?"], ["sequence?"] = utils["sequence?"], ["sym?"] = utils["sym?"], ["table?"] = utils["table?"], ["varg?"] = utils["varg?"], _AST = ast, _CHUNK = parent, _IS_COMPILER = true, _SCOPE = scope, _SPECIALS = compiler.scopes.global.specials, _VARARG = utils.varg(), comment = utils.comment, gensym = _548_, list = utils.list, macroexpand = _549_, metadata = compiler.metadata, sequence = utils.sequence, sym = utils.sym, unpack = unpack, version = utils.version, view = view} + env = {["assert-compile"] = compiler.assert, ["ast-source"] = utils["ast-source"], ["comment?"] = utils["comment?"], ["get-scope"] = _547_, ["in-scope?"] = _548_, ["list?"] = utils["list?"], ["macro-loaded"] = macro_loaded, ["multi-sym?"] = utils["multi-sym?"], ["sequence?"] = utils["sequence?"], ["sym?"] = utils["sym?"], ["table?"] = utils["table?"], ["varg?"] = utils["varg?"], _AST = ast, _CHUNK = parent, _IS_COMPILER = true, _SCOPE = scope, _SPECIALS = compiler.scopes.global.specials, _VARARG = utils.varg(), comment = utils.comment, gensym = _549_, list = utils.list, macroexpand = _550_, sequence = utils.sequence, sym = utils.sym, unpack = unpack, version = utils.version, view = view} env._G = env return setmetatable(env, {__index = provided, __newindex = provided, __pairs = combined_mt_pairs}) end - local function _550_(...) + local function _551_(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for c in string.gmatch((package.config or ""), "([^\n]+)") do @@ -2095,10 +2133,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - local _552_ = _550_(...) - local dirsep = _552_[1] - local pathsep = _552_[2] - local pathmark = _552_[3] + local _553_ = _551_(...) + local dirsep = _553_[1] + local pathsep = _553_[2] + local pathmark = _553_[3] local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or "?"), pathsep = (pathsep or ";")} local function escapepat(str) return string.gsub(str, "[^%w]", "%%%1") @@ -2111,36 +2149,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function try_path(path) local filename = path:gsub(escapepat(pkg_config.pathmark), no_dot_module) local filename2 = path:gsub(escapepat(pkg_config.pathmark), modulename) - local _553_0 = (io.open(filename) or io.open(filename2)) - if (nil ~= _553_0) then - local file = _553_0 + local _554_0 = (io.open(filename) or io.open(filename2)) + if (nil ~= _554_0) then + local file = _554_0 file:close() return filename else - local _ = _553_0 + local _ = _554_0 return nil, ("no file '" .. filename .. "'") end end local function find_in_path(start, _3ftried_paths) - local _555_0 = fullpath:match(pattern, start) - if (nil ~= _555_0) then - local path = _555_0 - local _556_0, _557_0 = try_path(path) - if (nil ~= _556_0) then - local filename = _556_0 + local _556_0 = fullpath:match(pattern, start) + if (nil ~= _556_0) then + local path = _556_0 + local _557_0, _558_0 = try_path(path) + if (nil ~= _557_0) then + local filename = _557_0 return filename - elseif ((_556_0 == nil) and (nil ~= _557_0)) then - local error = _557_0 - local function _559_() - local _558_0 = (_3ftried_paths or {}) - table.insert(_558_0, error) - return _558_0 + elseif ((_557_0 == nil) and (nil ~= _558_0)) then + local error = _558_0 + local function _560_() + local _559_0 = (_3ftried_paths or {}) + table.insert(_559_0, error) + return _559_0 end - return find_in_path((start + #path + 1), _559_()) + return find_in_path((start + #path + 1), _560_()) end else - local _ = _555_0 - local function _561_() + local _ = _556_0 + local function _562_() local tried_paths = table.concat((_3ftried_paths or {}), "\n\9") if (_VERSION < "Lua 5.4") then return ("\n\9" .. tried_paths) @@ -2148,31 +2186,31 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return tried_paths end end - return nil, _561_() + return nil, _562_() end end return find_in_path(1) end local function make_searcher(_3foptions) - local function _564_(module_name) + local function _565_(module_name) local opts = utils.copy(utils.root.options) for k, v in pairs((_3foptions or {})) do opts[k] = v end opts["module-name"] = module_name - local _565_0, _566_0 = search_module(module_name) - if (nil ~= _565_0) then - local filename = _565_0 - local function _567_(...) + local _566_0, _567_0 = search_module(module_name) + if (nil ~= _566_0) then + local filename = _566_0 + local function _568_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - return _567_, filename - elseif ((_565_0 == nil) and (nil ~= _566_0)) then - local error = _566_0 + return _568_, filename + elseif ((_566_0 == nil) and (nil ~= _567_0)) then + local error = _567_0 return error end end - return _564_ + return _565_ end local function dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) local searchers = (package.loaders or package.searchers or {}) @@ -2184,35 +2222,35 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function fennel_macro_searcher(module_name) local opts = nil do - local _569_0 = utils.copy(utils.root.options) - _569_0["module-name"] = module_name - _569_0["env"] = "_COMPILER" - _569_0["requireAsInclude"] = false - _569_0["allowedGlobals"] = nil - opts = _569_0 + local _570_0 = utils.copy(utils.root.options) + _570_0["module-name"] = module_name + _570_0["env"] = "_COMPILER" + _570_0["requireAsInclude"] = false + _570_0["allowedGlobals"] = nil + opts = _570_0 end - local _570_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) - if (nil ~= _570_0) then - local filename = _570_0 - local _571_ + local _571_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) + if (nil ~= _571_0) then + local filename = _571_0 + local _572_ if (opts["compiler-env"] == _G) then - local function _572_(...) + local function _573_(...) return dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) end - _571_ = _572_ + _572_ = _573_ else - local function _573_(...) + local function _574_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - _571_ = _573_ + _572_ = _574_ end - return _571_, filename + return _572_, filename end end local function lua_macro_searcher(module_name) - local _576_0 = search_module(module_name, package.path) - if (nil ~= _576_0) then - local filename = _576_0 + local _577_0 = search_module(module_name, package.path) + if (nil ~= _577_0) then + local filename = _577_0 local code = nil do local f = io.open(filename) @@ -2224,10 +2262,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _578_() + local function _579_() return assert(f:read("*a")) end - code = close_handlers_10_(_G.xpcall(_578_, (package.loaded.fennel or debug).traceback)) + code = close_handlers_10_(_G.xpcall(_579_, (package.loaded.fennel or debug).traceback)) end local chunk = load_code(code, make_compiler_env(), filename) return chunk, filename @@ -2235,35 +2273,38 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local macro_searchers = {fennel_macro_searcher, lua_macro_searcher} local function search_macro_module(modname, n) - local _580_0 = macro_searchers[n] - if (nil ~= _580_0) then - local f = _580_0 - local _581_0, _582_0 = f(modname) - if ((nil ~= _581_0) and true) then - local loader = _581_0 - local _3ffilename = _582_0 + local _581_0 = macro_searchers[n] + if (nil ~= _581_0) then + local f = _581_0 + local _582_0, _583_0 = f(modname) + if ((nil ~= _582_0) and true) then + local loader = _582_0 + local _3ffilename = _583_0 return loader, _3ffilename else - local _ = _581_0 + local _ = _582_0 return search_macro_module(modname, (n + 1)) end end end local function sandbox_fennel_module(modname) if ((modname == "fennel.macros") or (package and package.loaded and ("table" == type(package.loaded[modname])) and (package.loaded[modname].metadata == compiler.metadata))) then - return {metadata = compiler.metadata, view = view} + local function _586_(_, ...) + return (compiler.metadata):setall(...) + end + return {metadata = {setall = _586_}, view = view} end end - local function _586_(modname) - local function _587_() + local function _588_(modname) + local function _589_() local loader, filename = search_macro_module(modname, 1) compiler.assert(loader, (modname .. " module not found.")) macro_loaded[modname] = loader(modname, filename) return macro_loaded[modname] end - return (macro_loaded[modname] or sandbox_fennel_module(modname) or _587_()) + return (macro_loaded[modname] or sandbox_fennel_module(modname) or _589_()) end - safe_require = _586_ + safe_require = _588_ local function add_macros(macros_2a, ast, scope) compiler.assert(utils["table?"](macros_2a), "expected macros to be table", ast) for k, v in pairs(macros_2a) do @@ -2273,10 +2314,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return nil end - local function resolve_module_name(_588_0, _scope, _parent, opts) - local _589_ = _588_0 - local second = _589_[2] - local filename = _589_["filename"] + local function resolve_module_name(_590_0, _scope, _parent, opts) + local _591_ = _590_0 + local second = _591_[2] + local filename = _591_["filename"] local filename0 = (filename or (utils["table?"](second) and second.filename)) local module_name = utils.root.options["module-name"] local modexpr = compiler.compile(second, opts) @@ -2295,7 +2336,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if ("import-macros" == tostring(ast[1])) then return macro_loaded[modname] else - return add_macros(macro_loaded[modname], ast, scope, parent) + return add_macros(macro_loaded[modname], ast, scope) end end doc_special("require-macros", {"macro-module-name"}, "Load given module and use its contents as macro definitions in current scope.\nMacro module should return a table of macro functions with string keys.\nConsider using import-macros instead as it is more flexible.") @@ -2333,10 +2374,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _595_() + local function _597_() return assert(f:read("*all")):gsub("[\13\n]*$", "") end - src = close_handlers_10_(_G.xpcall(_595_, (package.loaded.fennel or debug).traceback)) + src = close_handlers_10_(_G.xpcall(_597_, (package.loaded.fennel or debug).traceback)) end local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement") local target = ("package.preload[%q]"):format(mod) @@ -2366,12 +2407,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local modexpr = nil do - local _598_0, _599_0 = pcall(resolve_module_name, ast, scope, parent, opts) - if ((_598_0 == true) and (nil ~= _599_0)) then - local modname = _599_0 + local _600_0, _601_0 = pcall(resolve_module_name, ast, scope, parent, opts) + if ((_600_0 == true) and (nil ~= _601_0)) then + local modname = _601_0 modexpr = utils.expr(string.format("%q", modname), "literal") else - local _ = _598_0 + local _ = _600_0 modexpr = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] end end @@ -2388,13 +2429,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct utils.root.options["module-name"] = mod _ = nil local res = nil - local function _603_() - local _602_0 = search_module(mod) - if (nil ~= _602_0) then - local fennel_path = _602_0 + local function _605_() + local _604_0 = search_module(mod) + if (nil ~= _604_0) then + local fennel_path = _604_0 return include_path(ast, opts, fennel_path, mod, true) else - local _0 = _602_0 + local _0 = _604_0 local lua_path = search_module(mod, package.path) if lua_path then return include_path(ast, opts, lua_path, mod, false) @@ -2405,7 +2446,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end end - res = ((utils["member?"](mod, (utils.root.options.skipInclude or {})) and opts.fallback(modexpr, true)) or include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _603_()) + res = ((utils["member?"](mod, (utils.root.options.skipInclude or {})) and opts.fallback(modexpr, true)) or include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _605_()) utils.root.options["module-name"] = oldmod return res end @@ -2422,9 +2463,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "Expected one table argument", ast) local macro_tbl = eval_compiler_2a(ast[2], scope, parent) compiler.assert(utils["table?"](macro_tbl), "Expected one table argument", ast) - return add_macros(macro_tbl, ast, scope, parent) + return add_macros(macro_tbl, ast, scope) end doc_special("macros", {"{:macro-name-1 (fn [...] ...) ... :macro-name-N macro-body-N}"}, "Define all functions in the given table as macros local to the current scope.") + SPECIALS["tail!"] = function(ast, scope, _parent, _609_0) + local _610_ = _609_0 + local tail = _610_["tail"] + compiler.assert((#ast == 2), "Expected one argument", ast) + compiler.assert(utils["list?"](ast[2]), "Expected a call as argument", ast) + compiler.assert(tail, "Must be in tail position", ast) + return compiler.compile(ast[2], {nval = 1, scope = scope}) + end + doc_special("tail!", {"body"}, "Assert that the body being called is in tail position.") SPECIALS["eval-compiler"] = function(ast, scope, parent) local old_first = ast[1] ast[1] = utils.sym("do") @@ -2447,13 +2497,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local scopes = {} local function make_scope(_3fparent) local parent = (_3fparent or scopes.global) - local _261_ + local _262_ if parent then - _261_ = ((parent.depth or 0) + 1) + _262_ = ((parent.depth or 0) + 1) else - _261_ = 0 + _262_ = 0 end - return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _261_, gensyms = setmetatable({}, {__index = (parent and parent.gensyms)}), hashfn = (parent and parent.hashfn), includes = setmetatable({}, {__index = (parent and parent.includes)}), macros = setmetatable({}, {__index = (parent and parent.macros)}), manglings = setmetatable({}, {__index = (parent and parent.manglings)}), parent = parent, refedglobals = {}, specials = setmetatable({}, {__index = (parent and parent.specials)}), symmeta = setmetatable({}, {__index = (parent and parent.symmeta)}), unmanglings = setmetatable({}, {__index = (parent and parent.unmanglings)}), vararg = (parent and parent.vararg)} + return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _262_, gensyms = setmetatable({}, {__index = (parent and parent.gensyms)}), hashfn = (parent and parent.hashfn), includes = setmetatable({}, {__index = (parent and parent.includes)}), macros = setmetatable({}, {__index = (parent and parent.macros)}), manglings = setmetatable({}, {__index = (parent and parent.manglings)}), parent = parent, refedglobals = {}, specials = setmetatable({}, {__index = (parent and parent.specials)}), symmeta = setmetatable({}, {__index = (parent and parent.symmeta)}), unmanglings = setmetatable({}, {__index = (parent and parent.unmanglings)}), vararg = (parent and parent.vararg)} end local function assert_msg(ast, msg) local ast_tbl = nil @@ -2471,10 +2521,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function assert_compile(condition, msg, ast, _3ffallback_ast) if not condition then - local _264_ = (utils.root.options or {}) - local error_pinpoint = _264_["error-pinpoint"] - local source = _264_["source"] - local unfriendly = _264_["unfriendly"] + local _265_ = (utils.root.options or {}) + local error_pinpoint = _265_["error-pinpoint"] + local source = _265_["source"] + local unfriendly = _265_["unfriendly"] local ast0 = nil if next(utils["ast-source"](ast)) then ast0 = ast @@ -2498,33 +2548,33 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct scopes.macro = scopes.global local serialize_subst = {["\11"] = "\\v", ["\12"] = "\\f", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "n"} local function serialize_string(str) - local function _269_(_241) + local function _270_(_241) return ("\\" .. _241:byte()) end - return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _269_) + return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _270_) end local function global_mangling(str) if utils["valid-lua-identifier?"](str) then return str else - local function _270_(_241) + local function _271_(_241) return string.format("_%02x", _241:byte()) end - return ("__fnl_global__" .. str:gsub("[^%w]", _270_)) + return ("__fnl_global__" .. str:gsub("[^%w]", _271_)) end end local function global_unmangling(identifier) - local _272_0 = string.match(identifier, "^__fnl_global__(.*)$") - if (nil ~= _272_0) then - local rest = _272_0 - local _273_0 = nil - local function _274_(_241) + local _273_0 = string.match(identifier, "^__fnl_global__(.*)$") + if (nil ~= _273_0) then + local rest = _273_0 + local _274_0 = nil + local function _275_(_241) return string.char(tonumber(_241:sub(2), 16)) end - _273_0 = string.gsub(rest, "_[%da-f][%da-f]", _274_) - return _273_0 + _274_0 = string.gsub(rest, "_[%da-f][%da-f]", _275_) + return _274_0 else - local _ = _272_0 + local _ = _273_0 return identifier end end @@ -2548,10 +2598,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct raw = str end local mangling = nil - local function _278_(_241) + local function _279_(_241) return string.format("_%02x", _241:byte()) end - mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _278_) + mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _279_) local unique = unique_mangling(mangling, mangling, scope, 0) scope.unmanglings[unique] = (scope["gensym-base"][str] or str) do @@ -2606,29 +2656,29 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(parts, ".") end local function autogensym(base, scope) - local _282_0 = utils["multi-sym?"](base) - if (nil ~= _282_0) then - local parts = _282_0 + local _283_0 = utils["multi-sym?"](base) + if (nil ~= _283_0) then + local parts = _283_0 return combine_auto_gensym(parts, autogensym(parts[1], scope)) else - local _ = _282_0 - local function _283_() + local _ = _283_0 + local function _284_() local mangling = gensym(scope, base:sub(1, ( - 2)), "auto") scope.autogensyms[base] = mangling return mangling end - return (scope.autogensyms[base] or _283_()) + return (scope.autogensyms[base] or _284_()) end end local function check_binding_valid(symbol, scope, ast, _3fopts) local name = tostring(symbol) local macro_3f = nil do - local _285_0 = _3fopts - if (nil ~= _285_0) then - _285_0 = _285_0["macro?"] + local _286_0 = _3fopts + if (nil ~= _286_0) then + _286_0 = _286_0["macro?"] end - macro_3f = _285_0 + macro_3f = _286_0 end assert_compile(not name:find("&"), "invalid character: &", symbol) assert_compile(not name:find("^%."), "invalid character: .", symbol) @@ -2726,22 +2776,22 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function flatten_chunk(file_sourcemap, chunk, tab, depth) if chunk.leaf then - local _297_ = utils["ast-source"](chunk.ast) - local filename = _297_["filename"] - local line = _297_["line"] + local _298_ = utils["ast-source"](chunk.ast) + local filename = _298_["filename"] + local line = _298_["line"] table.insert(file_sourcemap, {filename, line}) return chunk.leaf else local tab0 = nil do - local _298_0 = tab - if (_298_0 == true) then + local _299_0 = tab + if (_299_0 == true) then tab0 = " " - elseif (_298_0 == false) then + elseif (_299_0 == false) then tab0 = "" - elseif (_298_0 == tab) then + elseif (_299_0 == tab) then tab0 = tab - elseif (_298_0 == nil) then + elseif (_299_0 == nil) then tab0 = "" else tab0 = nil @@ -2787,7 +2837,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function make_metadata() - local function _306_(self, tgt, _3fkey) + local function _307_(self, tgt, _3fkey) if self[tgt] then if (nil ~= _3fkey) then return self[tgt][_3fkey] @@ -2796,12 +2846,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end end - local function _309_(self, tgt, key, value) + local function _310_(self, tgt, key, value) self[tgt] = (self[tgt] or {}) self[tgt][key] = value return tgt end - local function _310_(self, tgt, ...) + local function _311_(self, tgt, ...) local kv_len = select("#", ...) local kvs = {...} if ((kv_len % 2) ~= 0) then @@ -2813,7 +2863,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return tgt end - return setmetatable({}, {__index = {get = _306_, set = _309_, setall = _310_}, __mode = "k"}) + return setmetatable({}, {__index = {get = _307_, set = _310_, setall = _311_}, __mode = "k"}) end local function exprs1(exprs) return table.concat(utils.map(exprs, tostring), ", ") @@ -2859,14 +2909,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end if opts.target then local result = exprs1(exprs) - local function _318_() + local function _319_() if (result == "") then return "nil" else return result end end - emit(parent, string.format("%s = %s", opts.target, _318_()), ast) + emit(parent, string.format("%s = %s", opts.target, _319_()), ast) end if (opts.tail or opts.target) then return {returned = true} @@ -2878,16 +2928,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function find_macro(ast, scope) local macro_2a = nil do - local _321_0 = utils["sym?"](ast[1]) - if (_321_0 ~= nil) then - local _322_0 = tostring(_321_0) - if (_322_0 ~= nil) then - macro_2a = scope.macros[_322_0] + local _322_0 = utils["sym?"](ast[1]) + if (_322_0 ~= nil) then + local _323_0 = tostring(_322_0) + if (_323_0 ~= nil) then + macro_2a = scope.macros[_323_0] else - macro_2a = _322_0 + macro_2a = _323_0 end else - macro_2a = _321_0 + macro_2a = _322_0 end end local multi_sym_parts = utils["multi-sym?"](ast[1]) @@ -2899,12 +2949,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macro_2a end end - local function propagate_trace_info(_326_0, _index, node) - local _327_ = _326_0 - local byteend = _327_["byteend"] - local bytestart = _327_["bytestart"] - local filename = _327_["filename"] - local line = _327_["line"] + local function propagate_trace_info(_327_0, _index, node) + local _328_ = _327_0 + local byteend = _328_["byteend"] + local bytestart = _328_["bytestart"] + local filename = _328_["filename"] + local line = _328_["line"] do local src = utils["ast-source"](node) if (("table" == type(node)) and (filename ~= src.filename)) then @@ -2917,8 +2967,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function quote_literal_nils(index, node, parent) if (parent and utils["list?"](parent)) then for i = 1, utils.maxn(parent) do - local _329_0 = parent[i] - if (_329_0 == nil) then + local _330_0 = parent[i] + if (_330_0 == nil) then parent[i] = utils.sym("nil") end end @@ -2926,10 +2976,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return index, node, parent end local function comp(f, g) - local function _332_(...) + local function _333_(...) return f(g(...)) end - return _332_ + return _333_ end local function built_in_3f(m) local found_3f = false @@ -2940,36 +2990,36 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return found_3f end local function macroexpand_2a(ast, scope, _3fonce) - local _333_0 = nil + local _334_0 = nil if utils["list?"](ast) then - _333_0 = find_macro(ast, scope) + _334_0 = find_macro(ast, scope) else - _333_0 = nil + _334_0 = nil end - if (_333_0 == false) then + if (_334_0 == false) then return ast - elseif (nil ~= _333_0) then - local macro_2a = _333_0 + elseif (nil ~= _334_0) then + local macro_2a = _334_0 local old_scope = scopes.macro local _ = nil scopes.macro = scope _ = nil local ok, transformed = nil, nil - local function _335_() + local function _336_() return macro_2a(unpack(ast, 2)) end - local function _336_() + local function _337_() if built_in_3f(macro_2a) then return tostring else return debug.traceback end end - ok, transformed = xpcall(_335_, _336_()) - local function _337_(...) + ok, transformed = xpcall(_336_, _337_()) + local function _338_(...) return propagate_trace_info(ast, ...) end - utils["walk-tree"](transformed, comp(_337_, quote_literal_nils)) + utils["walk-tree"](transformed, comp(_338_, quote_literal_nils)) scopes.macro = old_scope assert_compile(ok, transformed, ast) if (_3fonce or not transformed) then @@ -2978,7 +3028,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macroexpand_2a(transformed, scope) end else - local _ = _333_0 + local _ = _334_0 return ast end end @@ -3010,13 +3060,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile((utils["sym?"](ast[1]) or utils["list?"](ast[1]) or ("string" == type(ast[1]))), ("cannot call literal value " .. tostring(ast[1])), ast) for i = 2, len do local subexprs = nil - local _343_ + local _344_ if (i ~= len) then - _343_ = 1 + _344_ = 1 else - _343_ = nil + _344_ = nil end - subexprs = compile1(ast[i], scope, parent, {nval = _343_}) + subexprs = compile1(ast[i], scope, parent, {nval = _344_}) table.insert(fargs, subexprs[1]) if (i == len) then for j = 2, #subexprs do @@ -3054,13 +3104,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_varg(ast, scope, parent, opts) - local _348_ + local _349_ if scope.hashfn then - _348_ = "use $... in hashfn" + _349_ = "use $... in hashfn" else - _348_ = "unexpected vararg" + _349_ = "unexpected vararg" end - assert_compile(scope.vararg, _348_, ast) + assert_compile(scope.vararg, _349_, ast) return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast) end local function compile_sym(ast, scope, parent, opts) @@ -3075,20 +3125,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return handle_compile_opts({e}, parent, opts, ast) end local function serialize_number(n) - local _351_0 = string.gsub(tostring(n), ",", ".") - return _351_0 + local _352_0 = string.gsub(tostring(n), ",", ".") + return _352_0 end local function compile_scalar(ast, _scope, parent, opts) local serialize = nil do - local _352_0 = type(ast) - if (_352_0 == "nil") then + local _353_0 = type(ast) + if (_353_0 == "nil") then serialize = tostring - elseif (_352_0 == "boolean") then + elseif (_353_0 == "boolean") then serialize = tostring - elseif (_352_0 == "string") then + elseif (_353_0 == "string") then serialize = serialize_string - elseif (_352_0 == "number") then + elseif (_353_0 == "number") then serialize = serialize_number else serialize = nil @@ -3101,8 +3151,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if ((type(k) == "string") and utils["valid-lua-identifier?"](k)) then return k else - local _354_ = compile1(k, scope, parent, {nval = 1}) - local compiled = _354_[1] + local _355_ = compile1(k, scope, parent, {nval = 1}) + local compiled = _355_[1] return ("[" .. tostring(compiled) .. "]") end end @@ -3128,12 +3178,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct do local tbl_17_ = buffer local i_18_ = #tbl_17_ - for k, v in utils.stablepairs(ast) do + for k in utils.stablepairs(ast) do local val_19_ = nil if not keys[k] then - local _357_ = compile1(ast[k], scope, parent, {nval = 1}) - local v0 = _357_[1] - val_19_ = string.format("%s = %s", escape_key(k), tostring(v0)) + local _358_ = compile1(ast[k], scope, parent, {nval = 1}) + local v = _358_[1] + val_19_ = string.format("%s = %s", escape_key(k), tostring(v)) else val_19_ = nil end @@ -3164,12 +3214,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function destructure(to, from, ast, scope, parent, opts) local opts0 = (opts or {}) - local _361_ = opts0 - local declaration = _361_["declaration"] - local forceglobal = _361_["forceglobal"] - local forceset = _361_["forceset"] - local isvar = _361_["isvar"] - local symtype = _361_["symtype"] + local _362_ = opts0 + local declaration = _362_["declaration"] + local forceglobal = _362_["forceglobal"] + local forceset = _362_["forceset"] + local isvar = _362_["isvar"] + local symtype = _362_["symtype"] local symtype0 = ("_" .. (symtype or "dst")) local setter = nil if declaration then @@ -3185,8 +3235,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return declare_local(symbol, nil, scope, symbol, new_manglings) else local parts = (utils["multi-sym?"](raw) or {raw}) - local _363_ = parts - local first = _363_[1] + local _364_ = parts + local first = _364_[1] local meta = scope.symmeta[first] assert_compile(not raw:find(":"), "cannot set method sym", symbol) if ((#parts == 1) and not forceset) then @@ -3207,14 +3257,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function compile_top_target(lvalues) local inits = nil - local function _368_(_241) + local function _369_(_241) if scope.manglings[_241] then return _241 else return "nil" end end - inits = utils.map(lvalues, _368_) + inits = utils.map(lvalues, _369_) local init = table.concat(inits, ", ") local lvalue = table.concat(lvalues, ", ") local plast = parent[#parent] @@ -3252,7 +3302,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local unpack_fn = "function (t, k, e)\n local mt = getmetatable(t)\n if 'table' == type(mt) and mt.__fennelrest then\n return mt.__fennelrest(t, k)\n elseif e then\n local rest = {}\n for k, v in pairs(t) do\n if not e[k] then rest[k] = v end\n end\n return rest\n else\n return {(table.unpack or unpack)(t, k)}\n end\n end" local function destructure_kv_rest(s, v, left, excluded_keys, destructure1) local exclude_str = nil - local _375_ + local _376_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3263,9 +3313,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _375_ = tbl_17_ + _376_ = tbl_17_ end - exclude_str = table.concat(_375_, ", ") + exclude_str = table.concat(_376_, ", ") local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_fn .. ")(%s, %s, {%s})"), "\n%s*", " "), s, tostring(v), exclude_str), "expression") return destructure1(v, {subexpr}, left) end @@ -3280,16 +3330,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local s = gensym(scope, symtype0) local right = nil do - local _377_0 = nil + local _378_0 = nil if top_3f then - _377_0 = exprs1(compile1(from, scope, parent)) + _378_0 = exprs1(compile1(from, scope, parent)) else - _377_0 = exprs1(rightexprs) + _378_0 = exprs1(rightexprs) end - if (_377_0 == "") then + if (_378_0 == "") then right = "nil" - elseif (nil ~= _377_0) then - local right0 = _377_0 + elseif (nil ~= _378_0) then + local right0 = _378_0 right = right0 else right = nil @@ -3394,8 +3444,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if opts.requireAsInclude then scope.specials.require = require_include end - local _391_ = utils.root - _391_["set-reset"](_391_) + if opts.assertAsRepl then + scope.macros.assert = scope.macros["assert-repl"] + end + local _393_ = utils.root + _393_["set-reset"](_393_) utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts for i = 1, #asts do local exprs = compile1(asts[i], scope, chunk, {nval = (((i < #asts) and 0) or nil), tail = (i == #asts)}) @@ -3446,14 +3499,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct info.currentline = (remap[info.currentline][2] or -1) end if (info.what == "Lua") then - local function _396_() + local function _398_() if info.name then return ("'" .. info.name .. "'") else return "?" end end - return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _396_()) + return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _398_()) elseif (info.short_src == "(tail call)") then return " (tail call)" else @@ -3477,11 +3530,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local done_3f, level = false, (_3fstart or 2) while not done_3f do do - local _400_0 = debug.getinfo(level, "Sln") - if (_400_0 == nil) then + local _402_0 = debug.getinfo(level, "Sln") + if (_402_0 == nil) then done_3f = true - elseif (nil ~= _400_0) then - local info = _400_0 + elseif (nil ~= _402_0) then + local info = _402_0 table.insert(lines, traceback_frame(info)) end end @@ -3491,14 +3544,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function entry_transform(fk, fv) - local function _403_(k, v) + local function _405_(k, v) if (type(k) == "number") then return k, fv(v) else return fk(k), fv(v) end end - return _403_ + return _405_ end local function mixed_concat(t, joiner) local seen = {} @@ -3543,10 +3596,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return res[1] elseif utils["list?"](form) then local mapped = nil - local function _408_() + local function _410_() return nil end - mapped = utils.kvmap(form, entry_transform(_408_, q)) + mapped = utils.kvmap(form, entry_transform(_410_, q)) local filename = nil if form.filename then filename = string.format("%q", form.filename) @@ -3564,13 +3617,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local _411_ + local _413_ if source then - _411_ = source.line + _413_ = source.line else - _411_ = "nil" + _413_ = "nil" end - return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _411_, "(getmetatable(sequence()))['sequence']") + return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _413_, "(getmetatable(sequence()))['sequence']") elseif (type(form) == "table") then local mapped = utils.kvmap(form, entry_transform(q, q)) local source = getmetatable(form) @@ -3580,14 +3633,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local function _414_() + local function _416_() if source then return source.line else return "nil" end end - return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _414_()) + return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _416_()) elseif (type(form) == "string") then return serialize_string(form) else @@ -3809,7 +3862,9 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( else r = getbyte({["stack-size"] = #stack}) end - byteindex = (byteindex + 1) + if r then + byteindex = (byteindex + 1) + end if (r and char_starter_3f(r)) then col = (col + 1) end @@ -3819,14 +3874,14 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return r end local function whitespace_3f(b) - local function _216_() - local _215_0 = options.whitespace - if (nil ~= _215_0) then - _215_0 = _215_0[b] + local function _217_() + local _216_0 = options.whitespace + if (nil ~= _216_0) then + _216_0 = _216_0[b] end - return _215_0 + return _216_0 end - return ((b == 32) or ((9 <= b) and (b <= 13)) or _216_()) + return ((b == 32) or ((9 <= b) and (b <= 13)) or _217_()) end local function parse_error(msg, _3fcol_adjust) local col0 = (col + (_3fcol_adjust or -1)) @@ -3846,25 +3901,25 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return nil end local function dispatch(v) - local _220_0 = stack[#stack] - if (_220_0 == nil) then + local _221_0 = stack[#stack] + if (_221_0 == nil) then retval, done_3f, whitespace_since_dispatch = v, true, false return nil - elseif ((_G.type(_220_0) == "table") and (nil ~= _220_0.prefix)) then - local prefix = _220_0.prefix + elseif ((_G.type(_221_0) == "table") and (nil ~= _221_0.prefix)) then + local prefix = _221_0.prefix local source0 = nil do - local _221_0 = table.remove(stack) - set_source_fields(_221_0) - source0 = _221_0 + local _222_0 = table.remove(stack) + set_source_fields(_222_0) + source0 = _222_0 end local list = utils.list(utils.sym(prefix, source0), v) for k, v0 in pairs(source0) do list[k] = v0 end return dispatch(list) - elseif (nil ~= _220_0) then - local top = _220_0 + elseif (nil ~= _221_0) then + local top = _221_0 whitespace_since_dispatch = false return table.insert(top, v) end @@ -3872,13 +3927,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( local close_table = nil local function badend(cause) local accum = utils.map(stack, "closer") - local _223_ + local _224_ if (#stack == 1) then - _223_ = "" + _224_ = "" else - _223_ = "s" + _224_ = "s" end - parse_error(string.format("expected closing delimiter%s %s", _223_, string.char(unpack(accum)))) + parse_error(string.format("expected closing delimiter%s %s", _224_, string.char(unpack(accum)))) if (cause == "eof") then for i = #accum, 2, -1 do close_table(accum[i]) @@ -3898,11 +3953,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local function parse_comment(b, contents) if (b and (10 ~= b)) then - local function _227_() + local function _228_() table.insert(contents, string.char(b)) return contents end - return parse_comment(getb(), _227_()) + return parse_comment(getb(), _228_()) elseif comments then ungetb(10) return dispatch(utils.comment(table.concat(contents), {filename = filename, line = line})) @@ -3928,12 +3983,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return dispatch(setmetatable(tbl, mt)) end local function add_comment_at(comments0, index, node) - local _231_0 = comments0[index] - if (nil ~= _231_0) then - local existing = _231_0 + local _232_0 = comments0[index] + if (nil ~= _232_0) then + local existing = _232_0 return table.insert(existing, node) else - local _ = _231_0 + local _ = _232_0 comments0[index] = {node} return nil end @@ -4013,16 +4068,16 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local state0 = nil do - local _242_0 = {state, b} - if ((_G.type(_242_0) == "table") and (_242_0[1] == "base") and (_242_0[2] == 92)) then + local _243_0 = {state, b} + if ((_G.type(_243_0) == "table") and (_243_0[1] == "base") and (_243_0[2] == 92)) then state0 = "backslash" - elseif ((_G.type(_242_0) == "table") and (_242_0[1] == "base") and (_242_0[2] == 34)) then + elseif ((_G.type(_243_0) == "table") and (_243_0[1] == "base") and (_243_0[2] == 34)) then state0 = "done" - elseif ((_G.type(_242_0) == "table") and (_242_0[1] == "backslash") and (_242_0[2] == 10)) then + elseif ((_G.type(_243_0) == "table") and (_243_0[1] == "backslash") and (_243_0[2] == 10)) then table.remove(chars, (#chars - 1)) state0 = "base" else - local _ = _242_0 + local _ = _243_0 state0 = "base" end end @@ -4044,11 +4099,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( table.remove(stack) local raw = table.concat(chars) local formatted = raw:gsub("[\7-\13]", escape_char) - local _246_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) - if (nil ~= _246_0) then - local load_fn = _246_0 + local _247_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) + if (nil ~= _247_0) then + local load_fn = _247_0 return dispatch(load_fn()) - elseif (_246_0 == nil) then + elseif (_247_0 == nil) then return parse_error(("Invalid string: " .. raw)) end end @@ -4081,13 +4136,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( dispatch((tonumber(number_with_stripped_underscores) or parse_error(("could not read number \"" .. rawstr .. "\"")))) return true else - local _252_0 = tonumber(number_with_stripped_underscores) - if (nil ~= _252_0) then - local x = _252_0 + local _253_0 = tonumber(number_with_stripped_underscores) + if (nil ~= _253_0) then + local x = _253_0 dispatch(x) return true else - local _ = _252_0 + local _ = _253_0 return false end end @@ -4134,7 +4189,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( elseif delims[b] then close_table0(b) elseif (b == 34) then - parse_string(b) + parse_string() elseif prefixes[b] then parse_prefix(b) elseif (sym_char_3f(b) or (b == string.byte("~"))) then @@ -4152,11 +4207,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return parse_loop(skip_whitespace(getb())) end - local function _259_() + local function _260_() stack, line, byteindex, col, lastb = {}, 1, 0, 0, nil return nil end - return parse_stream, _259_ + return parse_stream, _260_ end local function parser(stream_or_string, _3ffilename, _3foptions) local filename = (_3ffilename or "unknown") @@ -4788,7 +4843,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(...) local view = require("fennel.view") - local version = "1.3.2-dev" + local version = "1.4.0-dev" local function luajit_vm_3f() return ((nil ~= _G.jit) and (type(_G.jit) == "table") and (nil ~= _G.jit.on) and (nil ~= _G.jit.off) and (type(_G.jit.version_num) == "number")) end @@ -5256,7 +5311,8 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return symbol.quoted end local function idempotent_expr_3f(x) - return ((type(x) == "string") or (type(x) == "integer") or (type(x) == "number") or (sym_3f(x) and not multi_sym_3f(x))) + local t = type(x) + return ((t == "string") or (t == "integer") or (t == "number") or (t == "boolean") or (sym_3f(x) and not multi_sym_3f(x))) end local function ast_source(ast) if (table_3f(ast) or sequence_3f(ast)) then @@ -5391,14 +5447,14 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) local env = eval_env(opts.env, opts) local lua_source = compiler["compile-string"](str, opts) local loader = nil - local function _735_(...) + local function _746_(...) if opts.filename then return ("@" .. opts.filename) else return str end end - loader = specials["load-code"](lua_source, env, _735_(...)) + loader = specials["load-code"](lua_source, env, _746_(...)) opts.filename = nil return loader(...) end @@ -5423,10 +5479,10 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) out[k] = {["binding-form?"] = utils["member?"](k, binding_3f), ["body-form?"] = utils["member?"](k, body_3f), ["define?"] = utils["member?"](k, define_3f), ["macro?"] = true} end for k, v in pairs(_G) do - local _736_0 = type(v) - if (_736_0 == "function") then + local _747_0 = type(v) + if (_747_0 == "function") then out[k] = {["function?"] = true, ["global?"] = true} - elseif (_736_0 == "table") then + elseif (_747_0 == "table") then for k2, v2 in pairs(v) do if (("function" == type(v2)) and (k ~= "_G")) then out[(k .. "." .. k2)] = {["function?"] = true, ["global?"] = true} @@ -5446,19 +5502,21 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) do local module_name = "fennel.macros" local _ = nil - local function _739_() + local function _750_() return mod end - package.preload[module_name] = _739_ + package.preload[module_name] = _750_ _ = nil local env = nil do - local _740_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) - _740_0["utils"] = utils - _740_0["fennel"] = mod - env = _740_0 + local _751_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) + _751_0["utils"] = utils + _751_0["fennel"] = mod + env = _751_0 end - local built_ins = eval([===[;; These macros are awkward because their definition cannot rely on the any + local built_ins = eval([===[;; fennel-ls: macro-file + + ;; These macros are awkward because their definition cannot rely on the any ;; built-in macros, only special forms. (no when, no icollect, etc) (fn copy [t] @@ -5581,7 +5639,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (table.remove iter-out i))))) (assert (or (not found?) (sym? into) (table? into) (list? into)) "expected table, function call, or symbol in &into clause") - (values into iter-out)) + (values into iter-out found?)) (fn collect* [iter-tbl key-expr value-expr ...] "Return a table made by running an iterator and evaluating an expression that @@ -5619,17 +5677,22 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (assert (not= nil value-expr) "expected table value expression") (assert (= nil ...) "expected exactly one body expression. Wrap multiple expressions in do") - (let [(into iter) (extract-into iter-tbl)] - `(let [tbl# ,into] - ;; believe it or not, using a var here has a pretty good performance - ;; boost: https://p.hagelb.org/icollect-performance.html - (var i# (length tbl#)) - (,how ,iter - (let [val# ,value-expr] - (when (not= nil val#) - (set i# (+ i# 1)) - (tset tbl# i# val#)))) - tbl#))) + (let [(into iter has-into?) (extract-into iter-tbl)] + (if has-into? + `(let [tbl# ,into] + (,how ,iter (table.insert tbl# ,value-expr)) + tbl#) + ;; believe it or not, using a var here has a pretty good performance + ;; boost: https://p.hagelb.org/icollect-performance.html + ;; but it doesn't always work with &into clauses, so skip if that's used + `(let [tbl# []] + (var i# 0) + (,how ,iter + (let [val# ,value-expr] + (when (not= nil val#) + (set i# (+ i# 1)) + (tset tbl# i# val#)))) + tbl#)))) (fn icollect* [iter-tbl value-expr ...] "Return a sequential table made by running an iterator and evaluating an @@ -5763,7 +5826,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (.. "Expected n to be an integer >= 0, got " (tostring n))) (let [let-syms (list) let-values (if (= 1 (select "#" ...)) ... `(values ,...))] - (for [i 1 n] + (for [_ 1 n] (table.insert let-syms (gensym))) (if (= n 0) `(values) `(let [,let-syms ,let-values] @@ -5848,6 +5911,30 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (tset scope.macros import-key (. macros* macro-name)))))) nil) + (fn assert-repl* [condition message ?opts] + "Drop into a debug repl and print the message when condition is false/nil. + Takes an optional table of arguments which will be passed to fennel.repl." + (fn add-locals [{: symmeta : parent} locals] + (each [name (pairs symmeta)] + (tset locals name (sym name))) + (if parent (add-locals parent locals) locals)) + `(let [condition# ,condition + message# (or ,message "assertion failed, entering repl.")] + (if (not condition#) + (let [opts# (or ,?opts {:assert-repl? true + :readChunk (?. _G :___repl___ :readChunk) + :onError (?. _G :___repl___ :onError) + :onValued (?. _G :___repl___ :onValued)}) + fennel# (require (or opts#.moduleName :fennel)) + locals# ,(add-locals (get-scope) [])] + (set opts#.message (fennel#.traceback message#)) + (set opts#.env (collect [k# v# (pairs _G) &into locals#] + (if (= nil (. locals# k#)) (values k# v#)))) + (_G.assert (fennel#.repl opts#) message#)) + ;; `assert` returns *all* params on success, but omitting opts# to + ;; defensively prevent accidental leakage of REPL opts into code + (values condition# message#)))) + {:-> ->* :->> ->>* :-?> -?>* @@ -5868,14 +5955,17 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) :pick-values pick-values* :macro macro* :macrodebug macrodebug* - :import-macros import-macros*} + :import-macros import-macros* + :assert-repl assert-repl*} ]===], {env = env, filename = "src/fennel/macros.fnl", moduleName = module_name, scope = compiler.scopes.compiler, useMetadata = true}) local _0 = nil for k, v in pairs(built_ins) do compiler.scopes.global.macros[k] = v end _0 = nil - local match_macros = eval([===[;;; Pattern matching + local match_macros = eval([===[;; fennel-ls: macro-file + + ;;; Pattern matching ;; This is separated out so we can use the "core" macros during the ;; implementation of pattern matching. @@ -5978,7 +6068,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (let [in-pattern (symbols-in-pattern pattern)] (if ?symbols (do - (each [name symbol (pairs ?symbols)] + (each [name (pairs ?symbols)] (when (not (. in-pattern name)) (tset ?symbols name nil))) ?symbols) @@ -5994,7 +6084,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (if (= 0 (length bindings)) ;; no bindings special case generates simple code (let [condition - (icollect [i subpattern (ipairs pattern) &into `(or)] + (icollect [_ subpattern (ipairs pattern) &into `(or)] (let [(subcondition subbindings) (case-pattern vals subpattern unifications opts)] subcondition))] (values @@ -6007,7 +6097,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) bindings-mangled (icollect [_ binding (ipairs bindings)] (gensym (tostring binding))) pre-bindings `(if)] - (each [i subpattern (ipairs pattern)] + (each [_ subpattern (ipairs pattern)] (let [(subcondition subbindings) (case-guard vals subpattern guards {} case-pattern opts)] (table.insert pre-bindings subcondition) (table.insert pre-bindings `(let ,subbindings @@ -6173,7 +6263,7 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) (case-condition (list val) clauses match?) ;; protect against multiple evaluation of the value, bind against as ;; many values as we ever match against in the clauses. - (let [vals (fcollect [i 1 vals-count &into (list)] (gensym))] + (let [vals (fcollect [_ 1 vals-count &into (list)] (gensym))] (list `let [vals val] (case-condition vals clauses match?)))))) (fn case* [val ...] @@ -6269,20 +6359,20 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) 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 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-package-cpath PATH : Add PATH to package.cpath 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 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 : Don't 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 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 result\n\n --correlate : Make Lua output line numbers match Fennel input\n --load FILE (-l) : Load the specified FILE before executing command\n --no-compiler-sandbox : Don't limit compiler environment to minimal sandbox\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 --add-package-path PATH : Add PATH to package.path for finding Lua modules\n --add-package-cpath PATH : Add PATH to package.cpath 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 --assert-as-repl : Replace assert calls with assert-repl\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 --lua LUA_EXE : Run in a child process with LUA_EXE\n --plugin FILE : Activate the compiler plugin in FILE\n --raw-errors : Disable friendly compile error reporting\n --no-searcher : Skip installing package.searchers entry\n --no-fennelrc : Skip loading ~/.fennelrc when launching repl\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 _741_0 = {...} - _741_0["n"] = select("#", ...) - return _741_0 + local _752_0 = {...} + _752_0["n"] = select("#", ...) + return _752_0 end local function dosafely(f, ...) local args = {...} local result = nil - local function _742_() + local function _753_() return f(unpack(args)) end - result = pack(xpcall(_742_, fennel.traceback)) + result = pack(xpcall(_753_, fennel.traceback)) if not result[1] then do end (io.stderr):write((result[2] .. "\n")) os.exit(1) @@ -6327,19 +6417,18 @@ local function handle_lua(i) if (nil == arg[-1]) then do end (io.stderr):write("WARNING: --lua argument only works from script, not binary.\n") end - local ok = os.execute(table.concat(cmd, " ")) - local _747_ - if ok then - _747_ = 0 + local _758_0, _759_0 = os.execute(table.concat(cmd, " ")) + if (((_758_0 == true) and (_759_0 == "exit")) or (_758_0 == 0)) then + return os.exit(0, true) else - _747_ = 1 + local _ = _758_0 + return os.exit(1, true) end - return os.exit(_747_, true) end assert(arg, "Using the launcher from non-CLI context; use fennel.lua instead.") for i = #arg, 1, -1 do - local _749_0 = arg[i] - if (_749_0 == "--lua") then + local _761_0 = arg[i] + if (_761_0 == "--lua") then handle_lua(i) end end @@ -6347,55 +6436,58 @@ do local commands = {["-"] = true, ["--compile"] = true, ["--compile-binary"] = true, ["--eval"] = true, ["--help"] = true, ["--repl"] = true, ["--version"] = true, ["-c"] = true, ["-e"] = true, ["-h"] = true, ["-v"] = true} local i = 1 while (arg[i] and not options["ignore-options"]) do - local _751_0 = arg[i] - if (_751_0 == "--no-searcher") then + local _763_0 = arg[i] + if (_763_0 == "--no-searcher") then options["no-searcher"] = true table.remove(arg, i) - elseif (_751_0 == "--indent") then + elseif (_763_0 == "--indent") then options.indent = table.remove(arg, (i + 1)) if (options.indent == "false") then options.indent = false end table.remove(arg, i) - elseif (_751_0 == "--add-package-path") then + elseif (_763_0 == "--add-package-path") then local entry = table.remove(arg, (i + 1)) package.path = (entry .. ";" .. package.path) table.remove(arg, i) - elseif (_751_0 == "--add-package-cpath") then + elseif (_763_0 == "--add-package-cpath") then local entry = table.remove(arg, (i + 1)) package.cpath = (entry .. ";" .. package.cpath) table.remove(arg, i) - elseif (_751_0 == "--add-fennel-path") then + elseif (_763_0 == "--add-fennel-path") then local entry = table.remove(arg, (i + 1)) fennel.path = (entry .. ";" .. fennel.path) table.remove(arg, i) - elseif (_751_0 == "--add-macro-path") then + elseif (_763_0 == "--add-macro-path") then local entry = table.remove(arg, (i + 1)) fennel["macro-path"] = (entry .. ";" .. fennel["macro-path"]) table.remove(arg, i) - elseif (_751_0 == "--load") then + elseif (_763_0 == "--load") then handle_load(i) - elseif (_751_0 == "-l") then + elseif (_763_0 == "-l") then handle_load(i) - elseif (_751_0 == "--no-fennelrc") then + elseif (_763_0 == "--no-fennelrc") then options.fennelrc = false table.remove(arg, i) - elseif (_751_0 == "--correlate") then + elseif (_763_0 == "--correlate") then options.correlate = true table.remove(arg, i) - elseif (_751_0 == "--check-unused-locals") then + elseif (_763_0 == "--check-unused-locals") then options.checkUnusedLocals = true table.remove(arg, i) - elseif (_751_0 == "--globals") then + elseif (_763_0 == "--globals") then allow_globals(table.remove(arg, (i + 1)), _G) table.remove(arg, i) - elseif (_751_0 == "--globals-only") then + elseif (_763_0 == "--globals-only") then allow_globals(table.remove(arg, (i + 1)), {}) table.remove(arg, i) - elseif (_751_0 == "--require-as-include") then + elseif (_763_0 == "--require-as-include") then options.requireAsInclude = true table.remove(arg, i) - elseif (_751_0 == "--skip-include") then + elseif (_763_0 == "--assert-as-repl") then + options.assertAsRepl = true + table.remove(arg, i) + elseif (_763_0 == "--skip-include") then local skip_names = table.remove(arg, (i + 1)) local skip = nil do @@ -6412,28 +6504,28 @@ do end options.skipInclude = skip table.remove(arg, i) - elseif (_751_0 == "--use-bit-lib") then + elseif (_763_0 == "--use-bit-lib") then options.useBitLib = true table.remove(arg, i) - elseif (_751_0 == "--metadata") then + elseif (_763_0 == "--metadata") then options.useMetadata = true table.remove(arg, i) - elseif (_751_0 == "--no-metadata") then + elseif (_763_0 == "--no-metadata") then options.useMetadata = false table.remove(arg, i) - elseif (_751_0 == "--no-compiler-sandbox") then + elseif (_763_0 == "--no-compiler-sandbox") then options["compiler-env"] = _G table.remove(arg, i) - elseif (_751_0 == "--raw-errors") then + elseif (_763_0 == "--raw-errors") then options.unfriendly = true table.remove(arg, i) - elseif (_751_0 == "--plugin") then + elseif (_763_0 == "--plugin") then local opts = {["compiler-env"] = _G, env = "_COMPILER", useMetadata = true} local plugin = fennel.dofile(table.remove(arg, (i + 1)), opts) table.insert(options.plugins, 1, plugin) table.remove(arg, i) else - local _ = _751_0 + local _ = _763_0 if not commands[arg[i]] then options["ignore-options"] = true i = (i + 1) @@ -6469,25 +6561,25 @@ local function load_initfile() end local function repl() local readline_3f = (("dumb" ~= os.getenv("TERM")) and pcall(require, "readline")) + local welcome = {("Welcome to " .. fennel["runtime-version"]() .. "!"), "Use ,help to see available commands."} searcher_opts.useMetadata = (false ~= options.useMetadata) if (false ~= options.fennelrc) then options["fennelrc"] = load_initfile 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.") + table.insert(welcome, ("Try installing readline via luarocks for a " .. "better repl experience.")) end + options.message = table.concat(welcome, "\n") return fennel.repl(options) end local function eval(form) - local _761_ + local _773_ if (form == "-") then - _761_ = (io.stdin):read("*a") + _773_ = (io.stdin):read("*a") else - _761_ = form + _773_ = form end - return print(dosafely(fennel.eval, _761_, options)) + return print(dosafely(fennel.eval, _773_, options)) end local function compile(files) for _, filename in ipairs(files) do @@ -6499,17 +6591,17 @@ local function compile(files) f = assert(io.open(filename, "rb")) end do - local _764_0, _765_0 = nil, nil - local function _766_() + local _776_0, _777_0 = nil, nil + local function _778_() return fennel["compile-string"](f:read("*a"), options) end - _764_0, _765_0 = xpcall(_766_, fennel.traceback) - if ((_764_0 == true) and (nil ~= _765_0)) then - local val = _765_0 + _776_0, _777_0 = xpcall(_778_, fennel.traceback) + if ((_776_0 == true) and (nil ~= _777_0)) then + local val = _777_0 print(val) - elseif (true and (nil ~= _765_0)) then - local _0 = _764_0 - local msg = _765_0 + elseif (true and (nil ~= _777_0)) then + local _0 = _776_0 + local msg = _777_0 do end (io.stderr):write((msg .. "\n")) os.exit(1) end @@ -6518,57 +6610,56 @@ local function compile(files) end return nil end -local _768_0 = arg -local function _769_(...) +local _780_0 = arg +local function _781_(...) return (0 == #arg) end -if ((_G.type(_768_0) == "table") and _769_(...)) then +if ((_G.type(_780_0) == "table") and _781_(...)) then return repl() -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "--repl")) then +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--repl")) then return repl() -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "--compile")) then - local files = {select(2, (table.unpack or _G.unpack)(_768_0))} +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--compile")) then + local files = {select(2, (table.unpack or _G.unpack)(_780_0))} return compile(files) -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "-c")) then - local files = {select(2, (table.unpack or _G.unpack)(_768_0))} +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "-c")) then + local files = {select(2, (table.unpack or _G.unpack)(_780_0))} return compile(files) -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "--compile-binary") and (nil ~= _768_0[2]) and (nil ~= _768_0[3]) and (nil ~= _768_0[4]) and (nil ~= _768_0[5])) then - local filename = _768_0[2] - local out = _768_0[3] - local static_lua = _768_0[4] - local lua_include_dir = _768_0[5] - local args = {select(6, (table.unpack or _G.unpack)(_768_0))} +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--compile-binary") and (nil ~= _780_0[2]) and (nil ~= _780_0[3]) and (nil ~= _780_0[4]) and (nil ~= _780_0[5])) then + local filename = _780_0[2] + local out = _780_0[3] + local static_lua = _780_0[4] + local lua_include_dir = _780_0[5] + local args = {select(6, (table.unpack or _G.unpack)(_780_0))} 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(_768_0) == "table") and (_768_0[1] == "--compile-binary")) then +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--compile-binary")) then local cmd = (arg[0] or "fennel") return print((require("fennel.binary").help):format(cmd, cmd, cmd)) -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "--eval") and (nil ~= _768_0[2])) then - local form = _768_0[2] +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--eval") and (nil ~= _780_0[2])) then + local form = _780_0[2] return eval(form) -elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "-e") and (nil ~= _768_0[2])) then - local form = _768_0[2] +elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "-e") and (nil ~= _780_0[2])) then + local form = _780_0[2] return eval(form) else - local function _797_(...) - local a = _768_0[1] + local function _811_(...) + local a = _780_0[1] return ((a == "-v") or (a == "--version")) end - if (((_G.type(_768_0) == "table") and (nil ~= _768_0[1])) and _797_(...)) then - local a = _768_0[1] + if (((_G.type(_780_0) == "table") and (nil ~= _780_0[1])) and _811_(...)) then + local a = _780_0[1] return print(fennel["runtime-version"]()) - elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "--help")) then + elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "--help")) then return print(help) - elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "-h")) then + elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "-h")) then return print(help) - elseif ((_G.type(_768_0) == "table") and (_768_0[1] == "-")) then - local args = {select(2, (table.unpack or _G.unpack)(_768_0))} + elseif ((_G.type(_780_0) == "table") and (_780_0[1] == "-")) then return dosafely(fennel.eval, (io.stdin):read("*a")) - elseif ((_G.type(_768_0) == "table") and (nil ~= _768_0[1])) then - local filename = _768_0[1] - local args = {select(2, (table.unpack or _G.unpack)(_768_0))} + elseif ((_G.type(_780_0) == "table") and (nil ~= _780_0[1])) then + local filename = _780_0[1] + local args = {select(2, (table.unpack or _G.unpack)(_780_0))} arg[-2] = arg[-1] arg[-1] = arg[0] arg[0] = table.remove(arg, 1) diff --git a/src/fennel.lua b/src/fennel.lua index d8d1c2b..0461ff4 100644 --- a/src/fennel.lua +++ b/src/fennel.lua @@ -1,3 +1,5 @@ +-- SPDX-License-Identifier: MIT +-- SPDX-FileCopyrightText: Calvin Rose and contributors package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local utils = require("fennel.utils") local parser = require("fennel.parser") @@ -5,15 +7,16 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local specials = require("fennel.specials") local view = require("fennel.view") local unpack = (table.unpack or _G.unpack) - local function default_read_chunk(parser_state) - local function _607_() - if (0 < parser_state["stack-size"]) then - return ".." - else - return ">> " - end + local depth = 0 + local function prompt_for(top_3f) + if top_3f then + return (string.rep(">", (depth + 1)) .. " ") + else + return (string.rep(".", (depth + 1)) .. " ") end - io.write(_607_()) + end + local function default_read_chunk(parser_state) + io.write(prompt_for((0 == parser_state["stack-size"]))) io.flush() local input = io.read() return (input and (input .. "\n")) @@ -23,18 +26,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return io.write("\n") end local function default_on_error(errtype, err, lua_source) - local function _609_() - local _608_0 = errtype - if (_608_0 == "Lua Compile") then + local function _613_() + local _612_0 = errtype + if (_612_0 == "Lua Compile") then return ("Bad code generated - likely a bug with the compiler:\n" .. "--- Generated Lua Start ---\n" .. lua_source .. "--- Generated Lua End ---\n") - elseif (_608_0 == "Runtime") then + elseif (_612_0 == "Runtime") then return (compiler.traceback(tostring(err), 4) .. "\n") else - local _ = _608_0 + local _ = _612_0 return ("%s error: %s\n"):format(errtype, tostring(err)) end end - return io.write(_609_()) + return io.write(_613_()) end local function splice_save_locals(env, lua_source, scope) local saves = nil @@ -42,7 +45,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for name in pairs(env.___replLocals___) do - local val_19_ = ("local %s = ___replLocals___['%s']"):format((scope.manglings[name] or name), name) + local val_19_ = ("local %s = ___replLocals___[%q]"):format((scope.manglings[name] or name), name) if (nil ~= val_19_) then i_18_ = (i_18_ + 1) tbl_17_[i_18_] = val_19_ @@ -57,7 +60,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) for raw, name in pairs(scope.manglings) do local val_19_ = nil if not scope.gensyms[name] then - val_19_ = ("___replLocals___['%s'] = %s"):format(raw, name) + val_19_ = ("___replLocals___[%q] = %s"):format(raw, name) else val_19_ = nil end @@ -74,25 +77,25 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) else gap = " " end - local function _615_() + local function _619_() if next(saves) then return (table.concat(saves, " ") .. gap) else return "" end end - local function _618_() - local _616_0, _617_0 = lua_source:match("^(.*)[\n ](return .*)$") - if ((nil ~= _616_0) and (nil ~= _617_0)) then - local body = _616_0 - local _return = _617_0 + local function _622_() + local _620_0, _621_0 = lua_source:match("^(.*)[\n ](return .*)$") + if ((nil ~= _620_0) and (nil ~= _621_0)) then + local body = _620_0 + local _return = _621_0 return (body .. gap .. table.concat(binds, " ") .. gap .. _return) else - local _ = _616_0 + local _ = _620_0 return lua_source end end - return (_615_() .. _618_()) + return (_619_() .. _622_()) end local function completer(env, scope, text) local max_items = 2000 @@ -104,14 +107,14 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local scope_first_3f = ((tbl == env) or (tbl == env.___replLocals___)) local tbl_17_ = matches local i_18_ = #tbl_17_ - local function _620_() + local function _624_() if scope_first_3f then return scope.manglings else return tbl end end - for k, is_mangled in utils.allpairs(_620_()) do + for k, is_mangled in utils.allpairs(_624_()) do if (max_items <= #matches) then break end local val_19_ = nil do @@ -179,7 +182,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return input:match("^%s*,") end local function command_docs() - local _629_ + local _633_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -190,18 +193,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) tbl_17_[i_18_] = val_19_ end end - _629_ = tbl_17_ + _633_ = tbl_17_ end - return table.concat(_629_, "\n") + return table.concat(_633_, "\n") end commands.help = function(_, _0, on_values) - return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,exit - Leave the repl.\n\nUse ,doc something to see descriptions for individual macros and special forms.\n\nFor more information about the language, see https://fennel-lang.org/reference")}) + return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,return FORM - Evaluate FORM and return its value to the REPL's caller.\n ,exit - Leave the repl.\n\nUse ,doc something to see descriptions for individual macros and special forms.\nValues from previous inputs are kept in *1, *2, and *3.\n\nFor more information about the language, see https://fennel-lang.org/reference")}) end do end (compiler.metadata):set(commands.help, "fnl/docstring", "Show this message.") local function reload(module_name, env, on_values, on_error) - local _631_0, _632_0 = pcall(specials["load-code"]("return require(...)", env), module_name) - if ((_631_0 == true) and (nil ~= _632_0)) then - local old = _632_0 + local _635_0, _636_0 = pcall(specials["load-code"]("return require(...)", env), module_name) + if ((_635_0 == true) and (nil ~= _636_0)) then + local old = _636_0 local _ = nil package.loaded[module_name] = nil _ = nil @@ -226,8 +229,8 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) package.loaded[module_name] = old end return on_values({"ok"}) - elseif ((_631_0 == false) and (nil ~= _632_0)) then - local msg = _632_0 + elseif ((_635_0 == false) and (nil ~= _636_0)) then + local msg = _636_0 if msg:match("loop or previous error loading module") then package.loaded[module_name] = nil return reload(module_name, env, on_values, on_error) @@ -235,32 +238,32 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) specials["macro-loaded"][module_name] = nil return nil else - local function _637_() - local _636_0 = msg:gsub("\n.*", "") - return _636_0 + local function _641_() + local _640_0 = msg:gsub("\n.*", "") + return _640_0 end - return on_error("Runtime", _637_()) + return on_error("Runtime", _641_()) end end end local function run_command(read, on_error, f) - local _640_0, _641_0, _642_0 = pcall(read) - if ((_640_0 == true) and (_641_0 == true) and (nil ~= _642_0)) then - local val = _642_0 - local _643_0, _644_0 = pcall(f, val) - if ((_643_0 == false) and (nil ~= _644_0)) then - local msg = _644_0 + local _644_0, _645_0, _646_0 = pcall(read) + if ((_644_0 == true) and (_645_0 == true) and (nil ~= _646_0)) then + local val = _646_0 + local _647_0, _648_0 = pcall(f, val) + if ((_647_0 == false) and (nil ~= _648_0)) then + local msg = _648_0 return on_error("Runtime", msg) end - elseif (_640_0 == false) then + elseif (_644_0 == false) then return on_error("Parse", "Couldn't parse input.") end end commands.reload = function(env, read, on_values, on_error) - local function _647_(_241) + local function _651_(_241) return reload(tostring(_241), env, on_values, on_error) end - return run_command(read, on_error, _647_) + return run_command(read, on_error, _651_) end do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.") commands.reset = function(env, _, on_values) @@ -269,28 +272,28 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end do end (compiler.metadata):set(commands.reset, "fnl/docstring", "Erase all repl-local scope.") commands.complete = function(env, read, on_values, on_error, scope, chars) - local function _648_() + local function _652_() return on_values(completer(env, scope, table.concat(chars):gsub(",complete +", ""):sub(1, -2))) end - return run_command(read, on_error, _648_) + return run_command(read, on_error, _652_) end do end (compiler.metadata):set(commands.complete, "fnl/docstring", "Print all possible completions for a given input symbol.") local function apropos_2a(pattern, tbl, prefix, seen, names) for name, subtbl in pairs(tbl) do if (("string" == type(name)) and (package ~= subtbl)) then - local _649_0 = type(subtbl) - if (_649_0 == "function") then + local _653_0 = type(subtbl) + if (_653_0 == "function") then if ((prefix .. name)):match(pattern) then table.insert(names, (prefix .. name)) end - elseif (_649_0 == "table") then + elseif (_653_0 == "table") then if not seen[subtbl] then - local _651_ + local _655_ do seen[subtbl] = true - _651_ = seen + _655_ = seen end - apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _651_, names) + apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _655_, names) end end end @@ -311,10 +314,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return tbl_17_ end commands.apropos = function(_env, read, on_values, on_error, _scope) - local function _656_(_241) + local function _660_(_241) return on_values(apropos(tostring(_241))) end - return run_command(read, on_error, _656_) + return run_command(read, on_error, _660_) end do end (compiler.metadata):set(commands.apropos, "fnl/docstring", "Print all functions matching a pattern in all loaded modules.") local function apropos_follow_path(path) @@ -334,12 +337,12 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local tgt = package.loaded for _, path0 in ipairs(paths) do if (nil == tgt) then break end - local _659_ + local _663_ do - local _658_0 = path0:gsub("%/", ".") - _659_ = _658_0 + local _662_0 = path0:gsub("%/", ".") + _663_ = _662_0 end - tgt = tgt[_659_] + tgt = tgt[_663_] end return tgt end @@ -351,9 +354,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) do local tgt = apropos_follow_path(path) if ("function" == type(tgt)) then - local _660_0 = (compiler.metadata):get(tgt, "fnl/docstring") - if (nil ~= _660_0) then - local docstr = _660_0 + local _664_0 = (compiler.metadata):get(tgt, "fnl/docstring") + if (nil ~= _664_0) then + local docstr = _664_0 val_19_ = (docstr:match(pattern) and path) else val_19_ = nil @@ -370,125 +373,125 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return tbl_17_ end commands["apropos-doc"] = function(_env, read, on_values, on_error, _scope) - local function _664_(_241) + local function _668_(_241) return on_values(apropos_doc(tostring(_241))) end - return run_command(read, on_error, _664_) + return run_command(read, on_error, _668_) end do end (compiler.metadata):set(commands["apropos-doc"], "fnl/docstring", "Print all functions that match the pattern in their docs") local function apropos_show_docs(on_values, pattern) for _, path in ipairs(apropos(pattern)) do local tgt = apropos_follow_path(path) if (("function" == type(tgt)) and (compiler.metadata):get(tgt, "fnl/docstring")) then - on_values(specials.doc(tgt, path)) - on_values() + on_values({specials.doc(tgt, path)}) + on_values({}) end end return nil end commands["apropos-show-docs"] = function(_env, read, on_values, on_error) - local function _666_(_241) + local function _670_(_241) return apropos_show_docs(on_values, tostring(_241)) end - return run_command(read, on_error, _666_) + return run_command(read, on_error, _670_) end do end (compiler.metadata):set(commands["apropos-show-docs"], "fnl/docstring", "Print all documentations matching a pattern in function name") - local function resolve(identifier, _667_0, scope) - local _668_ = _667_0 - local env = _668_ - local ___replLocals___ = _668_["___replLocals___"] + local function resolve(identifier, _671_0, scope) + local _672_ = _671_0 + local env = _672_ + local ___replLocals___ = _672_["___replLocals___"] local e = nil - local function _669_(_241, _242) + local function _673_(_241, _242) return (___replLocals___[scope.unmanglings[_242]] or env[_242]) end - e = setmetatable({}, {__index = _669_}) - local function _670_(...) - local _671_0, _672_0 = ... - if ((_671_0 == true) and (nil ~= _672_0)) then - local code = _672_0 - local function _673_(...) - local _674_0, _675_0 = ... - if ((_674_0 == true) and (nil ~= _675_0)) then - local val = _675_0 + e = setmetatable({}, {__index = _673_}) + local function _674_(...) + local _675_0, _676_0 = ... + if ((_675_0 == true) and (nil ~= _676_0)) then + local code = _676_0 + local function _677_(...) + local _678_0, _679_0 = ... + if ((_678_0 == true) and (nil ~= _679_0)) then + local val = _679_0 return val else - local _ = _674_0 + local _ = _678_0 return nil end end - return _673_(pcall(specials["load-code"](code, e))) + return _677_(pcall(specials["load-code"](code, e))) else - local _ = _671_0 + local _ = _675_0 return nil end end - return _670_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) + return _674_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) end commands.find = function(env, read, on_values, on_error, scope) - local function _678_(_241) - local _679_0 = nil + local function _682_(_241) + local _683_0 = nil do - local _680_0 = utils["sym?"](_241) - if (nil ~= _680_0) then - local _681_0 = resolve(_680_0, env, scope) - if (nil ~= _681_0) then - _679_0 = debug.getinfo(_681_0) + local _684_0 = utils["sym?"](_241) + if (nil ~= _684_0) then + local _685_0 = resolve(_684_0, env, scope) + if (nil ~= _685_0) then + _683_0 = debug.getinfo(_685_0) else - _679_0 = _681_0 + _683_0 = _685_0 end else - _679_0 = _680_0 + _683_0 = _684_0 end end - if ((_G.type(_679_0) == "table") and (nil ~= _679_0.linedefined) and (nil ~= _679_0.short_src) and (nil ~= _679_0.source) and (_679_0.what == "Lua")) then - local line = _679_0.linedefined - local src = _679_0.short_src - local source = _679_0.source + if ((_G.type(_683_0) == "table") and (nil ~= _683_0.linedefined) and (nil ~= _683_0.short_src) and (nil ~= _683_0.source) and (_683_0.what == "Lua")) then + local line = _683_0.linedefined + local src = _683_0.short_src + local source = _683_0.source local fnlsrc = nil do - local _684_0 = compiler.sourcemap - if (nil ~= _684_0) then - _684_0 = _684_0[source] + local _688_0 = compiler.sourcemap + if (nil ~= _688_0) then + _688_0 = _688_0[source] end - if (nil ~= _684_0) then - _684_0 = _684_0[line] + if (nil ~= _688_0) then + _688_0 = _688_0[line] end - if (nil ~= _684_0) then - _684_0 = _684_0[2] + if (nil ~= _688_0) then + _688_0 = _688_0[2] end - fnlsrc = _684_0 + fnlsrc = _688_0 end return on_values({string.format("%s:%s", src, (fnlsrc or line))}) - elseif (_679_0 == nil) then + elseif (_683_0 == nil) then return on_error("Repl", "Unknown value") else - local _ = _679_0 + local _ = _683_0 return on_error("Repl", "No source info") end end - return run_command(read, on_error, _678_) + return run_command(read, on_error, _682_) end do end (compiler.metadata):set(commands.find, "fnl/docstring", "Print the filename and line number for a given function") commands.doc = function(env, read, on_values, on_error, scope) - local function _689_(_241) + local function _693_(_241) local name = tostring(_241) local path = (utils["multi-sym?"](name) or {name}) local ok_3f, target = nil, nil - local function _690_() + local function _694_() return (utils["get-in"](scope.specials, path) or utils["get-in"](scope.macros, path) or resolve(name, env, scope)) end - ok_3f, target = pcall(_690_) + ok_3f, target = pcall(_694_) if ok_3f then return on_values({specials.doc(target, name)}) else return on_error("Repl", ("Could not find " .. name .. " for docs.")) end end - return run_command(read, on_error, _689_) + return run_command(read, on_error, _693_) end do end (compiler.metadata):set(commands.doc, "fnl/docstring", "Print the docstring and arglist for a function, macro, or special form.") commands.compile = function(env, read, on_values, on_error, scope) - local function _692_(_241) + local function _696_(_241) local allowedGlobals = specials["current-global-names"](env) local ok_3f, result = pcall(compiler.compile, _241, {allowedGlobals = allowedGlobals, env = env, scope = scope}) if ok_3f then @@ -497,15 +500,15 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return on_error("Repl", ("Error compiling expression: " .. result)) end end - return run_command(read, on_error, _692_) + return run_command(read, on_error, _696_) end do end (compiler.metadata):set(commands.compile, "fnl/docstring", "compiles the expression into lua and prints the result.") local function load_plugin_commands(plugins) for i = #(plugins or {}), 1, -1 do for name, f in pairs(plugins[i]) do - local _694_0 = name:match("^repl%-command%-(.*)") - if (nil ~= _694_0) then - local cmd_name = _694_0 + local _698_0 = name:match("^repl%-command%-(.*)") + if (nil ~= _698_0) then + local cmd_name = _698_0 commands[cmd_name] = f end end @@ -515,19 +518,19 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local function run_command_loop(input, read, loop, env, on_values, on_error, scope, chars) local command_name = input:match(",([^%s/]+)") do - local _696_0 = commands[command_name] - if (nil ~= _696_0) then - local command = _696_0 + local _700_0 = commands[command_name] + if (nil ~= _700_0) then + local command = _700_0 command(env, read, on_values, on_error, scope, chars) else - local _ = _696_0 - if ("exit" ~= command_name) then + local _ = _700_0 + if ((command_name ~= "exit") and (command_name ~= "return")) then on_values({"Unknown command", command_name}) end end end if ("exit" ~= command_name) then - return loop() + return loop((command_name == "return")) end end local function try_readline_21(opts, ok, readline) @@ -570,9 +573,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end local function repl(_3foptions) local old_root_options = utils.root.options - local _705_ = utils.copy(_3foptions) - local opts = _705_ - local _3ffennelrc = _705_["fennelrc"] + local _709_ = utils.copy(_3foptions) + local opts = _709_ + local _3ffennelrc = _709_["fennelrc"] local _ = nil opts.fennelrc = nil _ = nil @@ -587,35 +590,42 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local callbacks = {env = env, onError = (opts.onError or default_on_error), onValues = (opts.onValues or default_on_values), pp = (opts.pp or view), readChunk = (opts.readChunk or default_read_chunk)} local save_locals_3f = (opts.saveLocals ~= false) local byte_stream, clear_stream = nil, nil - local function _707_(_241) + local function _711_(_241) return callbacks.readChunk(_241) end - byte_stream, clear_stream = parser.granulate(_707_) + byte_stream, clear_stream = parser.granulate(_711_) local chars = {} local read, reset = nil, nil - local function _708_(parser_state) + local function _712_(parser_state) local b = byte_stream(parser_state) if b then table.insert(chars, string.char(b)) end return b end - read, reset = parser.parser(_708_) + read, reset = parser.parser(_712_) + depth = (depth + 1) + if opts.message then + callbacks.onValues({opts.message}) + end env.___repl___ = callbacks opts.env, opts.scope = env, compiler["make-scope"]() opts.useMetadata = (opts.useMetadata ~= false) if (opts.allowedGlobals == nil) then opts.allowedGlobals = specials["current-global-names"](env) end + if opts.init then + opts.init(opts, depth) + end if opts.registerCompleter then - local function _712_() - local _711_0 = opts.scope - local function _713_(...) - return completer(env, _711_0, ...) + local function _718_() + local _717_0 = opts.scope + local function _719_(...) + return completer(env, _717_0, ...) end - return _713_ + return _719_ end - opts.registerCompleter(_712_()) + opts.registerCompleter(_718_()) end load_plugin_commands(opts.plugins) if save_locals_3f then @@ -636,12 +646,21 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return callbacks.onValues(out) end - local function loop() + local function save_value(...) + env.___replLocals___["*3"] = env.___replLocals___["*2"] + env.___replLocals___["*2"] = env.___replLocals___["*1"] + env.___replLocals___["*1"] = ... + return ... + end + opts.scope.manglings["*1"], opts.scope.unmanglings._1 = "_1", "*1" + opts.scope.manglings["*2"], opts.scope.unmanglings._2 = "_2", "*2" + opts.scope.manglings["*3"], opts.scope.unmanglings._3 = "_3", "*3" + local function loop(exit_next_3f) for k in pairs(chars) do chars[k] = nil end reset() - local ok, parser_not_eof_3f, x = pcall(read) + local ok, parser_not_eof_3f, form = pcall(read) local src_string = table.concat(chars) local readline_not_eof_3f = (not readline or (src_string ~= "(null)")) local not_eof_3f = (readline_not_eof_3f and parser_not_eof_3f) @@ -653,52 +672,66 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return run_command_loop(src_string, read, loop, env, callbacks.onValues, callbacks.onError, opts.scope, chars) else if not_eof_3f then - do - local _717_0, _718_0 = nil, nil - local function _719_() - opts["source"] = src_string - return opts - end - _717_0, _718_0 = pcall(compiler.compile, x, _719_()) - if ((_717_0 == false) and (nil ~= _718_0)) then - local msg = _718_0 + local function _723_(...) + local _724_0, _725_0 = ... + if ((_724_0 == true) and (nil ~= _725_0)) then + local src = _725_0 + local function _726_(...) + local _727_0, _728_0 = ... + if ((_727_0 == true) and (nil ~= _728_0)) then + local chunk = _728_0 + local function _729_() + return print_values(save_value(chunk())) + end + local function _730_(...) + return callbacks.onError("Runtime", ...) + end + return xpcall(_729_, _730_) + elseif ((_727_0 == false) and (nil ~= _728_0)) then + local msg = _728_0 + clear_stream() + return callbacks.onError("Compile", msg) + end + end + local function _733_(...) + local src0 = nil + if save_locals_3f then + src0 = splice_save_locals(env, src, opts.scope) + else + src0 = src + end + return pcall(specials["load-code"], src0, env) + end + return _726_(_733_(...)) + elseif ((_724_0 == false) and (nil ~= _725_0)) then + local msg = _725_0 clear_stream() - callbacks.onError("Compile", msg) - elseif ((_717_0 == true) and (nil ~= _718_0)) then - local src = _718_0 - local src0 = nil - if save_locals_3f then - src0 = splice_save_locals(env, src, opts.scope) - else - src0 = src - end - local _721_0, _722_0 = pcall(specials["load-code"], src0, env) - if ((_721_0 == false) and (nil ~= _722_0)) then - local msg = _722_0 - clear_stream() - callbacks.onError("Lua Compile", msg, src0) - elseif (true and (nil ~= _722_0)) then - local _1 = _721_0 - local chunk = _722_0 - local function _723_() - return print_values(chunk()) - end - local function _724_(...) - return callbacks.onError("Runtime", ...) - end - xpcall(_723_, _724_) - end + return callbacks.onError("Compile", msg) end end + local function _735_() + opts["source"] = src_string + return opts + end + _723_(pcall(compiler.compile, form, _735_())) utils.root.options = old_root_options - return loop() + if exit_next_3f then + return env.___replLocals___["*1"] + else + return loop() + end end end end - loop() + local value = loop() + depth = (depth - 1) if readline then - return readline.save_history() + readline.save_history() end + if opts.exit then + opts.exit(opts, depth) + end + return value end return repl end @@ -710,14 +743,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local unpack = (table.unpack or _G.unpack) local SPECIALS = compiler.scopes.global.specials local function wrap_env(env) - local function _416_(_, key) + local function _418_(_, key) if utils["string?"](key) then return env[compiler["global-unmangling"](key)] else return env[key] end end - local function _418_(_, key, value) + local function _420_(_, key, value) if utils["string?"](key) then env[compiler["global-unmangling"](key)] = value return nil @@ -726,26 +759,26 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return nil end end - local function _420_() + local function _422_() local function putenv(k, v) - local _421_ + local _423_ if utils["string?"](k) then - _421_ = compiler["global-unmangling"](k) + _423_ = compiler["global-unmangling"](k) else - _421_ = k + _423_ = k end - return _421_, v + return _423_, v end return next, utils.kvmap(env, putenv), nil end - return setmetatable({}, {__index = _416_, __newindex = _418_, __pairs = _420_}) + return setmetatable({}, {__index = _418_, __newindex = _420_, __pairs = _422_}) end local function current_global_names(_3fenv) local mt = nil do - local _423_0 = getmetatable(_3fenv) - if ((_G.type(_423_0) == "table") and (nil ~= _423_0.__pairs)) then - local mtpairs = _423_0.__pairs + local _425_0 = getmetatable(_3fenv) + if ((_G.type(_425_0) == "table") and (nil ~= _425_0.__pairs)) then + local mtpairs = _425_0.__pairs local tbl_14_ = {} for k, v in mtpairs(_3fenv) do local k_15_, v_16_ = k, v @@ -754,7 +787,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end mt = tbl_14_ - elseif (_423_0 == nil) then + elseif (_425_0 == nil) then mt = (_3fenv or _G) else mt = nil @@ -764,15 +797,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function load_code(code, _3fenv, _3ffilename) local env = (_3fenv or rawget(_G, "_ENV") or _G) - local _426_0, _427_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") - if ((nil ~= _426_0) and (nil ~= _427_0)) then - local setfenv = _426_0 - local loadstring = _427_0 + local _428_0, _429_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") + if ((nil ~= _428_0) and (nil ~= _429_0)) then + local setfenv = _428_0 + local loadstring = _429_0 local f = assert(loadstring(code, _3ffilename)) setfenv(f, env) return f else - local _ = _426_0 + local _ = _428_0 return assert(load(code, _3ffilename, "t", env)) end end @@ -784,13 +817,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local mt = getmetatable(tgt) if ((type(tgt) == "function") or ((type(mt) == "table") and (type(mt.__call) == "function"))) then local arglist = table.concat(((compiler.metadata):get(tgt, "fnl/arglist") or {"#"}), " ") - local _429_ + local _431_ if (0 < #arglist) then - _429_ = " " + _431_ = " " else - _429_ = "" + _431_ = "" end - return string.format("(%s%s%s)\n %s", name, _429_, arglist, docstring) + return string.format("(%s%s%s)\n %s", name, _431_, arglist, docstring) else return string.format("%s\n %s", name, docstring) end @@ -817,16 +850,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local retexprs = {returned = true} utils.hook("customhook-early-do", ast, sub_scope) local function compile_body(outer_target, outer_tail, outer_retexprs) - if (len < start) then - compiler.compile1(nil, sub_scope, chunk, {tail = outer_tail, target = outer_target}) - else - for i = start, len do - local subopts = {nval = (((i ~= len) and 0) or opts.nval), tail = (((i == len) and outer_tail) or nil), target = (((i == len) and outer_target) or nil)} - local _ = utils["propagate-options"](opts, subopts) - local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts) - if (i ~= len) then - compiler["keep-side-effects"](subexprs, parent, nil, ast[i]) - end + for i = start, len do + local subopts = {nval = (((i ~= len) and 0) or opts.nval), tail = (((i == len) and outer_tail) or nil), target = (((i == len) and outer_target) or nil)} + local _ = utils["propagate-options"](opts, subopts) + local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts) + if (i ~= len) then + compiler["keep-side-effects"](subexprs, parent, nil, ast[i]) end end compiler.emit(parent, chunk, ast) @@ -904,9 +933,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local opts = {nval = 1, tail = false} local scope = compiler["make-scope"]() local chunk = {} - local _440_ = compiler.compile1(v, scope, chunk, opts) - local _441_ = _440_[1] - local v0 = _441_[1] + local _441_ = compiler.compile1(v, scope, chunk, opts) + local _442_ = _441_[1] + local v0 = _442_[1] return v0 end local function insert_meta(meta, k, v) @@ -914,23 +943,23 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((type(k) == "string"), ("expected string keys in metadata table, got: %s"):format(view(k, view_opts))) compiler.assert(literal_3f(v), ("expected literal value in metadata table, got: %s %s"):format(view(k, view_opts), view(v, view_opts))) table.insert(meta, view(k)) - local function _442_() + local function _443_() if ("string" == type(v)) then return view(v, view_opts) else return compile_value(v) end end - table.insert(meta, _442_()) + table.insert(meta, _443_()) return meta end local function insert_arglist(meta, arg_list) local view_opts = {["escape-newlines?"] = true, ["line-length"] = math.huge, ["one-line?"] = true} table.insert(meta, "\"fnl/arglist\"") - local function _443_(_241) + local function _444_(_241) return view(view(_241, view_opts)) end - table.insert(meta, ("{" .. table.concat(utils.map(arg_list, _443_), ", ") .. "}")) + table.insert(meta, ("{" .. table.concat(utils.map(arg_list, _444_), ", ") .. "}")) return meta end local function set_fn_metadata(f_metadata, parent, fn_name) @@ -949,13 +978,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function get_fn_name(ast, scope, fn_name, multi) if (fn_name and (fn_name[1] ~= "nil")) then - local _446_ + local _447_ if not multi then - _446_ = compiler["declare-local"](fn_name, {}, scope, ast) + _447_ = compiler["declare-local"](fn_name, {}, scope, ast) else - _446_ = compiler["symbol-to-expression"](fn_name, scope)[1] + _447_ = compiler["symbol-to-expression"](fn_name, scope)[1] end - return _446_, not multi, 3 + return _447_, not multi, 3 else return nil, true, 2 end @@ -965,13 +994,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct for i = (index + 1), #ast do compiler.compile1(ast[i], f_scope, f_chunk, {nval = (((i ~= #ast) and 0) or nil), tail = (i == #ast)}) end - local _449_ + local _450_ if local_3f then - _449_ = "local function %s(%s)" + _450_ = "local function %s(%s)" else - _449_ = "%s = function(%s)" + _450_ = "%s = function(%s)" end - compiler.emit(parent, string.format(_449_, fn_name, table.concat(arg_name_list, ", ")), ast) + compiler.emit(parent, string.format(_450_, fn_name, table.concat(arg_name_list, ", ")), ast) compiler.emit(parent, f_chunk, ast) compiler.emit(parent, "end", ast) set_fn_metadata(f_metadata, parent, fn_name) @@ -993,7 +1022,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function get_function_metadata(ast, arg_list, index) - local function _452_(_241, _242) + local function _453_(_241, _242) local tbl_14_ = _241 for k, v in pairs(_242) do local k_15_, v_16_ = k, v @@ -1003,18 +1032,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_14_ end - local function _454_(_241, _242) + local function _455_(_241, _242) _241["fnl/docstring"] = _242 return _241 end - return maybe_metadata(ast, utils["kv-table?"], _452_, maybe_metadata(ast, utils["string?"], _454_, {["fnl/arglist"] = arg_list}, index)) + return maybe_metadata(ast, utils["kv-table?"], _453_, maybe_metadata(ast, utils["string?"], _455_, {["fnl/arglist"] = arg_list}, index)) end SPECIALS.fn = function(ast, scope, parent) local f_scope = nil do - local _455_0 = compiler["make-scope"](scope) - _455_0["vararg"] = false - f_scope = _455_0 + local _456_0 = compiler["make-scope"](scope) + _456_0["vararg"] = false + f_scope = _456_0 end local f_chunk = {} local fn_sym = utils["sym?"](ast[2]) @@ -1074,36 +1103,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("fn", {"name?", "args", "docstring?", "..."}, "Function syntax. May optionally include a name and docstring or a metadata table.\nIf a name is provided, the function will be bound in the current scope.\nWhen called with the wrong number of args, excess args will be discarded\nand lacking args will be nil, use lambda for arity-checked functions.", true) SPECIALS.lua = function(ast, _, parent) compiler.assert(((#ast == 2) or (#ast == 3)), "expected 1 or 2 arguments", ast) - local _460_ + local _461_ do - local _459_0 = utils["sym?"](ast[2]) - if (nil ~= _459_0) then - _460_ = tostring(_459_0) + local _460_0 = utils["sym?"](ast[2]) + if (nil ~= _460_0) then + _461_ = tostring(_460_0) else - _460_ = _459_0 + _461_ = _460_0 end end - if ("nil" ~= _460_) then + if ("nil" ~= _461_) then table.insert(parent, {ast = ast, leaf = tostring(ast[2])}) end - local _464_ + local _465_ do - local _463_0 = utils["sym?"](ast[3]) - if (nil ~= _463_0) then - _464_ = tostring(_463_0) + local _464_0 = utils["sym?"](ast[3]) + if (nil ~= _464_0) then + _465_ = tostring(_464_0) else - _464_ = _463_0 + _465_ = _464_0 end end - if ("nil" ~= _464_) then + if ("nil" ~= _465_) then return tostring(ast[3]) end end local function dot(ast, scope, parent) compiler.assert((1 < #ast), "expected table argument", ast) local len = #ast - local _467_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local lhs = _467_[1] + local _468_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local lhs = _468_[1] if (len == 2) then return tostring(lhs) else @@ -1113,8 +1142,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if (utils["string?"](index) and utils["valid-lua-identifier?"](index)) then table.insert(indices, ("." .. index)) else - local _468_ = compiler.compile1(index, scope, parent, {nval = 1}) - local index0 = _468_[1] + local _469_ = compiler.compile1(index, scope, parent, {nval = 1}) + local index0 = _469_[1] table.insert(indices, ("[" .. tostring(index0) .. "]")) end end @@ -1159,7 +1188,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end doc_special("var", {"name", "val"}, "Introduce new mutable local.") local function kv_3f(t) - local _472_ + local _473_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1175,9 +1204,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _472_ = tbl_17_ + _473_ = tbl_17_ end - return _472_[1] + return _473_[1] end SPECIALS.let = function(ast, scope, parent, opts) local bindings = ast[2] @@ -1204,22 +1233,22 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function disambiguate_3f(rootstr, parent) - local function _477_() - local _476_0 = get_prev_line(parent) - if (nil ~= _476_0) then - local prev_line = _476_0 + local function _478_() + local _477_0 = get_prev_line(parent) + if (nil ~= _477_0) then + local prev_line = _477_0 return prev_line:match("%)$") end end - return (rootstr:match("^{") or rootstr:match("^%(") or _477_()) + return (rootstr:match("^{") or rootstr:match("^%(") or _478_()) end SPECIALS.tset = function(ast, scope, parent) compiler.assert((3 < #ast), "expected table, key, and value arguments", ast) local root = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] local keys = {} for i = 3, (#ast - 1) do - local _479_ = compiler.compile1(ast[i], scope, parent, {nval = 1}) - local key = _479_[1] + local _480_ = compiler.compile1(ast[i], scope, parent, {nval = 1}) + local key = _480_[1] table.insert(keys, tostring(key)) end local value = compiler.compile1(ast[#ast], scope, parent, {nval = 1})[1] @@ -1233,7 +1262,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return compiler.emit(parent, fmtstr:format(rootstr, table.concat(keys, "]["), tostring(value)), ast) end doc_special("tset", {"tbl", "key1", "...", "keyN", "val"}, "Set the value of a table field. Can take additional keys to set\nnested values, but all parents must contain an existing table.") - local function calculate_target(scope, opts) + local function calculate_if_target(scope, opts) if not (opts.tail or opts.target or opts.nval) then return "iife", true, nil elseif (opts.nval and (opts.nval ~= 0) and not opts.target) then @@ -1262,7 +1291,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct else local do_scope = compiler["make-scope"](scope) local branches = {} - local wrapper, inner_tail, inner_target, target_exprs = calculate_target(scope, opts) + local wrapper, inner_tail, inner_target, target_exprs = calculate_if_target(scope, opts) local body_opts = {nval = opts.nval, tail = inner_tail, target = inner_target} local function compile_body(i) local chunk = {} @@ -1346,15 +1375,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function compile_until(condition, scope, chunk) if condition then - local _490_ = compiler.compile1(condition, scope, chunk, {nval = 1}) - local condition_lua = _490_[1] + local _491_ = compiler.compile1(condition, scope, chunk, {nval = 1}) + local condition_lua = _491_[1] return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(condition, "expression")) end end SPECIALS.each = function(ast, scope, parent) compiler.assert((3 <= #ast), "expected body expression", ast[1]) compiler.assert(utils["table?"](ast[2]), "expected binding table", ast) - compiler.assert((2 <= #ast[2]), "expected binding and iterator", ast) local binding = setmetatable(utils.copy(ast[2]), getmetatable(ast[2])) local until_condition = remove_until_condition(binding) local iter = table.remove(binding, #binding) @@ -1376,6 +1404,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local vals = compiler.compile1(iter, scope, parent) local val_names = utils.map(vals, tostring) local chunk = {} + compiler.assert(bind_vars[1], "expected binding and iterator", ast) compiler.emit(parent, ("for %s in %s do"):format(table.concat(bind_vars, ", "), table.concat(val_names, ", ")), ast) for raw, args in utils.stablepairs(destructures) do compiler.destructure(args, raw, ast, sub_scope, chunk, {declaration = true, nomulti = true, symtype = "each"}) @@ -1433,10 +1462,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct SPECIALS["for"] = for_2a doc_special("for", {"[index start stop step?]", "..."}, "Numeric loop construct.\nEvaluates body once for each value between start and stop (inclusive).", true) local function native_method_call(ast, _scope, _parent, target, args) - local _494_ = ast - local _ = _494_[1] - local _0 = _494_[2] - local method_string = _494_[3] + local _495_ = ast + local _ = _495_[1] + local _0 = _495_[2] + local method_string = _495_[3] local call_string = nil if ((target.type == "literal") or (target.type == "varg") or (target.type == "expression")) then call_string = "(%s):%s(%s)" @@ -1458,18 +1487,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function method_call(ast, scope, parent) compiler.assert((2 < #ast), "expected at least 2 arguments", ast) - local _496_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local target = _496_[1] + local _497_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local target = _497_[1] local args = {} for i = 4, #ast do local subexprs = nil - local _497_ + local _498_ if (i ~= #ast) then - _497_ = 1 + _498_ = 1 else - _497_ = nil + _498_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _497_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _498_}) utils.map(subexprs, tostring, args) end if (utils["string?"](ast[3]) and utils["valid-lua-identifier?"](ast[3])) then @@ -1484,14 +1513,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special(":", {"tbl", "method-name", "..."}, "Call the named method on tbl with the provided args.\nMethod name doesn't have to be known at compile-time; if it is, use\n(tbl:method-name ...) instead.") SPECIALS.comment = function(ast, _, parent) local c = nil - local _500_ + local _501_ do local tbl_17_ = {} local i_18_ = #tbl_17_ for i, elt in ipairs(ast) do local val_19_ = nil if (i ~= 1) then - val_19_ = view(ast[i], {["one-line?"] = true}) + val_19_ = view(elt, {["one-line?"] = true}) else val_19_ = nil end @@ -1500,9 +1529,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _500_ = tbl_17_ + _501_ = tbl_17_ end - c = table.concat(_500_, " "):gsub("%]%]", "]\\]") + c = table.concat(_501_, " "):gsub("%]%]", "]\\]") return compiler.emit(parent, ("--[[ " .. c .. " ]]"), ast) end doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true) @@ -1523,10 +1552,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local f_scope = nil do - local _505_0 = compiler["make-scope"](scope) - _505_0["vararg"] = false - _505_0["hashfn"] = true - f_scope = _505_0 + local _506_0 = compiler["make-scope"](scope) + _506_0["vararg"] = false + _506_0["hashfn"] = true + f_scope = _506_0 end local f_chunk = {} local name = compiler.gensym(scope) @@ -1567,17 +1596,17 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return utils.expr(name, "sym") end doc_special("hashfn", {"..."}, "Function literal shorthand; args are either $... OR $1, $2, etc.") - local function maybe_short_circuit_protect(ast, i, name, _510_0) - local _511_ = _510_0 - local mac = _511_["macros"] + local function maybe_short_circuit_protect(ast, i, name, _511_0) + local _512_ = _511_0 + local mac = _512_["macros"] local call = (utils["list?"](ast) and tostring(ast[1])) if ((("or" == name) or ("and" == name)) and (1 < i) and (mac[call] or ("set" == call) or ("tset" == call) or ("global" == call))) then - return utils.list(utils.sym("do"), ast) + return utils.list(utils.list(utils.sym("fn"), utils.sequence(utils.varg()), ast)) else return ast end end - local function arithmetic_special(name, zero_arity, unary_prefix, ast, scope, parent) + local function operator_special(name, zero_arity, unary_prefix, ast, scope, parent) local len = #ast local operands = {} local padded_op = (" " .. name .. " ") @@ -1590,15 +1619,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct table.insert(operands, tostring(subexprs[1])) end end - local _514_0 = #operands - if (_514_0 == 0) then - local _515_ + local _515_0 = #operands + if (_515_0 == 0) then + local _516_ do compiler.assert(zero_arity, "Expected more than 0 arguments", ast) - _515_ = zero_arity + _516_ = zero_arity end - return utils.expr(_515_, "literal") - elseif (_514_0 == 1) then + return utils.expr(_516_, "literal") + elseif (_515_0 == 1) then if utils["varg?"](ast[2]) then return compiler.assert(false, "tried to use vararg with operator", ast) elseif unary_prefix then @@ -1607,20 +1636,20 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return operands[1] end else - local _ = _514_0 + local _ = _515_0 return ("(" .. table.concat(operands, padded_op) .. ")") end end local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name) - local _519_ + local _520_ do - local _518_0 = (_3flua_name or name) - local function _520_(...) - return arithmetic_special(_518_0, zero_arity, unary_prefix, ...) + local _519_0 = (_3flua_name or name) + local function _521_(...) + return operator_special(_519_0, zero_arity, unary_prefix, ...) end - _519_ = _520_ + _520_ = _521_ end - SPECIALS[name] = _519_ + SPECIALS[name] = _520_ return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.") end define_arithmetic_special("+", "0") @@ -1632,10 +1661,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct define_arithmetic_special("/", nil, "1") define_arithmetic_special("//", nil, "1") SPECIALS["or"] = function(ast, scope, parent) - return arithmetic_special("or", "false", nil, ast, scope, parent) + return operator_special("or", "false", nil, ast, scope, parent) end SPECIALS["and"] = function(ast, scope, parent) - return arithmetic_special("and", "true", nil, ast, scope, parent) + return operator_special("and", "true", nil, ast, scope, parent) end doc_special("and", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.") doc_special("or", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.") @@ -1649,13 +1678,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local prefixed_lib_name = ("bit." .. lib_name) for i = 2, len do local subexprs = nil - local _521_ + local _522_ if (i ~= len) then - _521_ = 1 + _522_ = 1 else - _521_ = nil + _522_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _521_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _522_}) utils.map(subexprs, tostring, operands) end if (#operands == 1) then @@ -1674,10 +1703,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function define_bitop_special(name, zero_arity, unary_prefix, native) - local function _527_(...) + local function _528_(...) return bitop_special(native, name, zero_arity, unary_prefix, ...) end - SPECIALS[name] = _527_ + SPECIALS[name] = _528_ return nil end define_bitop_special("lshift", nil, "1", "<<") @@ -1692,8 +1721,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("bxor", {"x1", "x2", "..."}, "Bitwise XOR of any number of arguments.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.") SPECIALS.bnot = function(ast, scope, parent) compiler.assert((#ast == 2), "expected one argument", ast) - local _528_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local value = _528_[1] + local _529_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local value = _529_[1] if utils.root.options.useBitLib then return ("bit.bnot(" .. tostring(value) .. ")") else @@ -1702,15 +1731,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end doc_special("bnot", {"x"}, "Bitwise negation; only works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.") doc_special("..", {"a", "b", "..."}, "String concatenation operator; works the same as Lua but accepts more arguments.") - local function native_comparator(op, _530_0, scope, parent) - local _531_ = _530_0 - local _ = _531_[1] - local lhs_ast = _531_[2] - local rhs_ast = _531_[3] - local _532_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) - local lhs = _532_[1] - local _533_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) - local rhs = _533_[1] + local function native_comparator(op, _531_0, scope, parent) + local _532_ = _531_0 + local _ = _532_[1] + local lhs_ast = _532_[2] + local rhs_ast = _532_[3] + local _533_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) + local lhs = _533_[1] + local _534_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) + local rhs = _534_[1] return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs)) end local function idempotent_comparator(op, chain_op, ast, scope, parent) @@ -1823,21 +1852,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local safe_require = nil local function safe_compiler_env() - local _540_ + local _541_ do - local _539_0 = rawget(_G, "utf8") - if (nil ~= _539_0) then - _540_ = utils.copy(_539_0) + local _540_0 = rawget(_G, "utf8") + if (nil ~= _540_0) then + _541_ = utils.copy(_540_0) else - _540_ = _539_0 + _541_ = _540_0 end end - return {_VERSION = _VERSION, assert = assert, bit = rawget(_G, "bit"), error = error, getmetatable = safe_getmetatable, ipairs = ipairs, math = utils.copy(math), next = next, pairs = utils.stablepairs, pcall = pcall, print = print, rawequal = rawequal, rawget = rawget, rawlen = rawget(_G, "rawlen"), rawset = rawset, require = safe_require, select = select, setmetatable = setmetatable, string = utils.copy(string), table = utils.copy(table), tonumber = tonumber, tostring = tostring, type = type, utf8 = _540_, xpcall = xpcall} + return {_VERSION = _VERSION, assert = assert, bit = rawget(_G, "bit"), error = error, getmetatable = safe_getmetatable, ipairs = ipairs, math = utils.copy(math), next = next, pairs = utils.stablepairs, pcall = pcall, print = print, rawequal = rawequal, rawget = rawget, rawlen = rawget(_G, "rawlen"), rawset = rawset, require = safe_require, select = select, setmetatable = setmetatable, string = utils.copy(string), table = utils.copy(table), tonumber = tonumber, tostring = tostring, type = type, utf8 = _541_, xpcall = xpcall} end local function combined_mt_pairs(env) local combined = {} - local _542_ = getmetatable(env) - local __index = _542_["__index"] + local _543_ = getmetatable(env) + local __index = _543_["__index"] if ("table" == type(__index)) then for k, v in pairs(__index) do combined[k] = v @@ -1851,40 +1880,40 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function make_compiler_env(ast, scope, parent, _3fopts) local provided = nil do - local _544_0 = (_3fopts or utils.root.options) - if ((_G.type(_544_0) == "table") and (_544_0["compiler-env"] == "strict")) then + local _545_0 = (_3fopts or utils.root.options) + if ((_G.type(_545_0) == "table") and (_545_0["compiler-env"] == "strict")) then provided = safe_compiler_env() - elseif ((_G.type(_544_0) == "table") and (nil ~= _544_0.compilerEnv)) then - local compilerEnv = _544_0.compilerEnv + elseif ((_G.type(_545_0) == "table") and (nil ~= _545_0.compilerEnv)) then + local compilerEnv = _545_0.compilerEnv provided = compilerEnv - elseif ((_G.type(_544_0) == "table") and (nil ~= _544_0["compiler-env"])) then - local compiler_env = _544_0["compiler-env"] + elseif ((_G.type(_545_0) == "table") and (nil ~= _545_0["compiler-env"])) then + local compiler_env = _545_0["compiler-env"] provided = compiler_env else - local _ = _544_0 - provided = safe_compiler_env(false) + local _ = _545_0 + provided = safe_compiler_env() end end local env = nil - local function _546_() + local function _547_() return compiler.scopes.macro end - local function _547_(symbol) + local function _548_(symbol) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.scopes.macro.manglings[tostring(symbol)] end - local function _548_(base) + local function _549_(base) return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base)) end - local function _549_(form) + local function _550_(form) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.macroexpand(form, compiler.scopes.macro) end - env = {["assert-compile"] = compiler.assert, ["ast-source"] = utils["ast-source"], ["comment?"] = utils["comment?"], ["get-scope"] = _546_, ["in-scope?"] = _547_, ["list?"] = utils["list?"], ["macro-loaded"] = macro_loaded, ["multi-sym?"] = utils["multi-sym?"], ["sequence?"] = utils["sequence?"], ["sym?"] = utils["sym?"], ["table?"] = utils["table?"], ["varg?"] = utils["varg?"], _AST = ast, _CHUNK = parent, _IS_COMPILER = true, _SCOPE = scope, _SPECIALS = compiler.scopes.global.specials, _VARARG = utils.varg(), comment = utils.comment, gensym = _548_, list = utils.list, macroexpand = _549_, metadata = compiler.metadata, sequence = utils.sequence, sym = utils.sym, unpack = unpack, version = utils.version, view = view} + env = {["assert-compile"] = compiler.assert, ["ast-source"] = utils["ast-source"], ["comment?"] = utils["comment?"], ["get-scope"] = _547_, ["in-scope?"] = _548_, ["list?"] = utils["list?"], ["macro-loaded"] = macro_loaded, ["multi-sym?"] = utils["multi-sym?"], ["sequence?"] = utils["sequence?"], ["sym?"] = utils["sym?"], ["table?"] = utils["table?"], ["varg?"] = utils["varg?"], _AST = ast, _CHUNK = parent, _IS_COMPILER = true, _SCOPE = scope, _SPECIALS = compiler.scopes.global.specials, _VARARG = utils.varg(), comment = utils.comment, gensym = _549_, list = utils.list, macroexpand = _550_, sequence = utils.sequence, sym = utils.sym, unpack = unpack, version = utils.version, view = view} env._G = env return setmetatable(env, {__index = provided, __newindex = provided, __pairs = combined_mt_pairs}) end - local function _550_(...) + local function _551_(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for c in string.gmatch((package.config or ""), "([^\n]+)") do @@ -1896,10 +1925,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - local _552_ = _550_(...) - local dirsep = _552_[1] - local pathsep = _552_[2] - local pathmark = _552_[3] + local _553_ = _551_(...) + local dirsep = _553_[1] + local pathsep = _553_[2] + local pathmark = _553_[3] local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or "?"), pathsep = (pathsep or ";")} local function escapepat(str) return string.gsub(str, "[^%w]", "%%%1") @@ -1912,36 +1941,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function try_path(path) local filename = path:gsub(escapepat(pkg_config.pathmark), no_dot_module) local filename2 = path:gsub(escapepat(pkg_config.pathmark), modulename) - local _553_0 = (io.open(filename) or io.open(filename2)) - if (nil ~= _553_0) then - local file = _553_0 + local _554_0 = (io.open(filename) or io.open(filename2)) + if (nil ~= _554_0) then + local file = _554_0 file:close() return filename else - local _ = _553_0 + local _ = _554_0 return nil, ("no file '" .. filename .. "'") end end local function find_in_path(start, _3ftried_paths) - local _555_0 = fullpath:match(pattern, start) - if (nil ~= _555_0) then - local path = _555_0 - local _556_0, _557_0 = try_path(path) - if (nil ~= _556_0) then - local filename = _556_0 + local _556_0 = fullpath:match(pattern, start) + if (nil ~= _556_0) then + local path = _556_0 + local _557_0, _558_0 = try_path(path) + if (nil ~= _557_0) then + local filename = _557_0 return filename - elseif ((_556_0 == nil) and (nil ~= _557_0)) then - local error = _557_0 - local function _559_() - local _558_0 = (_3ftried_paths or {}) - table.insert(_558_0, error) - return _558_0 + elseif ((_557_0 == nil) and (nil ~= _558_0)) then + local error = _558_0 + local function _560_() + local _559_0 = (_3ftried_paths or {}) + table.insert(_559_0, error) + return _559_0 end - return find_in_path((start + #path + 1), _559_()) + return find_in_path((start + #path + 1), _560_()) end else - local _ = _555_0 - local function _561_() + local _ = _556_0 + local function _562_() local tried_paths = table.concat((_3ftried_paths or {}), "\n\9") if (_VERSION < "Lua 5.4") then return ("\n\9" .. tried_paths) @@ -1949,31 +1978,31 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return tried_paths end end - return nil, _561_() + return nil, _562_() end end return find_in_path(1) end local function make_searcher(_3foptions) - local function _564_(module_name) + local function _565_(module_name) local opts = utils.copy(utils.root.options) for k, v in pairs((_3foptions or {})) do opts[k] = v end opts["module-name"] = module_name - local _565_0, _566_0 = search_module(module_name) - if (nil ~= _565_0) then - local filename = _565_0 - local function _567_(...) + local _566_0, _567_0 = search_module(module_name) + if (nil ~= _566_0) then + local filename = _566_0 + local function _568_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - return _567_, filename - elseif ((_565_0 == nil) and (nil ~= _566_0)) then - local error = _566_0 + return _568_, filename + elseif ((_566_0 == nil) and (nil ~= _567_0)) then + local error = _567_0 return error end end - return _564_ + return _565_ end local function dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) local searchers = (package.loaders or package.searchers or {}) @@ -1985,35 +2014,35 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function fennel_macro_searcher(module_name) local opts = nil do - local _569_0 = utils.copy(utils.root.options) - _569_0["module-name"] = module_name - _569_0["env"] = "_COMPILER" - _569_0["requireAsInclude"] = false - _569_0["allowedGlobals"] = nil - opts = _569_0 + local _570_0 = utils.copy(utils.root.options) + _570_0["module-name"] = module_name + _570_0["env"] = "_COMPILER" + _570_0["requireAsInclude"] = false + _570_0["allowedGlobals"] = nil + opts = _570_0 end - local _570_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) - if (nil ~= _570_0) then - local filename = _570_0 - local _571_ + local _571_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) + if (nil ~= _571_0) then + local filename = _571_0 + local _572_ if (opts["compiler-env"] == _G) then - local function _572_(...) + local function _573_(...) return dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) end - _571_ = _572_ + _572_ = _573_ else - local function _573_(...) + local function _574_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - _571_ = _573_ + _572_ = _574_ end - return _571_, filename + return _572_, filename end end local function lua_macro_searcher(module_name) - local _576_0 = search_module(module_name, package.path) - if (nil ~= _576_0) then - local filename = _576_0 + local _577_0 = search_module(module_name, package.path) + if (nil ~= _577_0) then + local filename = _577_0 local code = nil do local f = io.open(filename) @@ -2025,10 +2054,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _578_() + local function _579_() return assert(f:read("*a")) end - code = close_handlers_10_(_G.xpcall(_578_, (package.loaded.fennel or debug).traceback)) + code = close_handlers_10_(_G.xpcall(_579_, (package.loaded.fennel or debug).traceback)) end local chunk = load_code(code, make_compiler_env(), filename) return chunk, filename @@ -2036,35 +2065,38 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local macro_searchers = {fennel_macro_searcher, lua_macro_searcher} local function search_macro_module(modname, n) - local _580_0 = macro_searchers[n] - if (nil ~= _580_0) then - local f = _580_0 - local _581_0, _582_0 = f(modname) - if ((nil ~= _581_0) and true) then - local loader = _581_0 - local _3ffilename = _582_0 + local _581_0 = macro_searchers[n] + if (nil ~= _581_0) then + local f = _581_0 + local _582_0, _583_0 = f(modname) + if ((nil ~= _582_0) and true) then + local loader = _582_0 + local _3ffilename = _583_0 return loader, _3ffilename else - local _ = _581_0 + local _ = _582_0 return search_macro_module(modname, (n + 1)) end end end local function sandbox_fennel_module(modname) if ((modname == "fennel.macros") or (package and package.loaded and ("table" == type(package.loaded[modname])) and (package.loaded[modname].metadata == compiler.metadata))) then - return {metadata = compiler.metadata, view = view} + local function _586_(_, ...) + return (compiler.metadata):setall(...) + end + return {metadata = {setall = _586_}, view = view} end end - local function _586_(modname) - local function _587_() + local function _588_(modname) + local function _589_() local loader, filename = search_macro_module(modname, 1) compiler.assert(loader, (modname .. " module not found.")) macro_loaded[modname] = loader(modname, filename) return macro_loaded[modname] end - return (macro_loaded[modname] or sandbox_fennel_module(modname) or _587_()) + return (macro_loaded[modname] or sandbox_fennel_module(modname) or _589_()) end - safe_require = _586_ + safe_require = _588_ local function add_macros(macros_2a, ast, scope) compiler.assert(utils["table?"](macros_2a), "expected macros to be table", ast) for k, v in pairs(macros_2a) do @@ -2074,10 +2106,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return nil end - local function resolve_module_name(_588_0, _scope, _parent, opts) - local _589_ = _588_0 - local second = _589_[2] - local filename = _589_["filename"] + local function resolve_module_name(_590_0, _scope, _parent, opts) + local _591_ = _590_0 + local second = _591_[2] + local filename = _591_["filename"] local filename0 = (filename or (utils["table?"](second) and second.filename)) local module_name = utils.root.options["module-name"] local modexpr = compiler.compile(second, opts) @@ -2096,7 +2128,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if ("import-macros" == tostring(ast[1])) then return macro_loaded[modname] else - return add_macros(macro_loaded[modname], ast, scope, parent) + return add_macros(macro_loaded[modname], ast, scope) end end doc_special("require-macros", {"macro-module-name"}, "Load given module and use its contents as macro definitions in current scope.\nMacro module should return a table of macro functions with string keys.\nConsider using import-macros instead as it is more flexible.") @@ -2134,10 +2166,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _595_() + local function _597_() return assert(f:read("*all")):gsub("[\13\n]*$", "") end - src = close_handlers_10_(_G.xpcall(_595_, (package.loaded.fennel or debug).traceback)) + src = close_handlers_10_(_G.xpcall(_597_, (package.loaded.fennel or debug).traceback)) end local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement") local target = ("package.preload[%q]"):format(mod) @@ -2167,12 +2199,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local modexpr = nil do - local _598_0, _599_0 = pcall(resolve_module_name, ast, scope, parent, opts) - if ((_598_0 == true) and (nil ~= _599_0)) then - local modname = _599_0 + local _600_0, _601_0 = pcall(resolve_module_name, ast, scope, parent, opts) + if ((_600_0 == true) and (nil ~= _601_0)) then + local modname = _601_0 modexpr = utils.expr(string.format("%q", modname), "literal") else - local _ = _598_0 + local _ = _600_0 modexpr = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] end end @@ -2189,13 +2221,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct utils.root.options["module-name"] = mod _ = nil local res = nil - local function _603_() - local _602_0 = search_module(mod) - if (nil ~= _602_0) then - local fennel_path = _602_0 + local function _605_() + local _604_0 = search_module(mod) + if (nil ~= _604_0) then + local fennel_path = _604_0 return include_path(ast, opts, fennel_path, mod, true) else - local _0 = _602_0 + local _0 = _604_0 local lua_path = search_module(mod, package.path) if lua_path then return include_path(ast, opts, lua_path, mod, false) @@ -2206,7 +2238,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end end - res = ((utils["member?"](mod, (utils.root.options.skipInclude or {})) and opts.fallback(modexpr, true)) or include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _603_()) + res = ((utils["member?"](mod, (utils.root.options.skipInclude or {})) and opts.fallback(modexpr, true)) or include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _605_()) utils.root.options["module-name"] = oldmod return res end @@ -2223,9 +2255,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "Expected one table argument", ast) local macro_tbl = eval_compiler_2a(ast[2], scope, parent) compiler.assert(utils["table?"](macro_tbl), "Expected one table argument", ast) - return add_macros(macro_tbl, ast, scope, parent) + return add_macros(macro_tbl, ast, scope) end doc_special("macros", {"{:macro-name-1 (fn [...] ...) ... :macro-name-N macro-body-N}"}, "Define all functions in the given table as macros local to the current scope.") + SPECIALS["tail!"] = function(ast, scope, _parent, _609_0) + local _610_ = _609_0 + local tail = _610_["tail"] + compiler.assert((#ast == 2), "Expected one argument", ast) + compiler.assert(utils["list?"](ast[2]), "Expected a call as argument", ast) + compiler.assert(tail, "Must be in tail position", ast) + return compiler.compile(ast[2], {nval = 1, scope = scope}) + end + doc_special("tail!", {"body"}, "Assert that the body being called is in tail position.") SPECIALS["eval-compiler"] = function(ast, scope, parent) local old_first = ast[1] ast[1] = utils.sym("do") @@ -2248,13 +2289,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local scopes = {} local function make_scope(_3fparent) local parent = (_3fparent or scopes.global) - local _261_ + local _262_ if parent then - _261_ = ((parent.depth or 0) + 1) + _262_ = ((parent.depth or 0) + 1) else - _261_ = 0 + _262_ = 0 end - return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _261_, gensyms = setmetatable({}, {__index = (parent and parent.gensyms)}), hashfn = (parent and parent.hashfn), includes = setmetatable({}, {__index = (parent and parent.includes)}), macros = setmetatable({}, {__index = (parent and parent.macros)}), manglings = setmetatable({}, {__index = (parent and parent.manglings)}), parent = parent, refedglobals = {}, specials = setmetatable({}, {__index = (parent and parent.specials)}), symmeta = setmetatable({}, {__index = (parent and parent.symmeta)}), unmanglings = setmetatable({}, {__index = (parent and parent.unmanglings)}), vararg = (parent and parent.vararg)} + return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _262_, gensyms = setmetatable({}, {__index = (parent and parent.gensyms)}), hashfn = (parent and parent.hashfn), includes = setmetatable({}, {__index = (parent and parent.includes)}), macros = setmetatable({}, {__index = (parent and parent.macros)}), manglings = setmetatable({}, {__index = (parent and parent.manglings)}), parent = parent, refedglobals = {}, specials = setmetatable({}, {__index = (parent and parent.specials)}), symmeta = setmetatable({}, {__index = (parent and parent.symmeta)}), unmanglings = setmetatable({}, {__index = (parent and parent.unmanglings)}), vararg = (parent and parent.vararg)} end local function assert_msg(ast, msg) local ast_tbl = nil @@ -2272,10 +2313,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function assert_compile(condition, msg, ast, _3ffallback_ast) if not condition then - local _264_ = (utils.root.options or {}) - local error_pinpoint = _264_["error-pinpoint"] - local source = _264_["source"] - local unfriendly = _264_["unfriendly"] + local _265_ = (utils.root.options or {}) + local error_pinpoint = _265_["error-pinpoint"] + local source = _265_["source"] + local unfriendly = _265_["unfriendly"] local ast0 = nil if next(utils["ast-source"](ast)) then ast0 = ast @@ -2299,33 +2340,33 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct scopes.macro = scopes.global local serialize_subst = {["\11"] = "\\v", ["\12"] = "\\f", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "n"} local function serialize_string(str) - local function _269_(_241) + local function _270_(_241) return ("\\" .. _241:byte()) end - return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _269_) + return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _270_) end local function global_mangling(str) if utils["valid-lua-identifier?"](str) then return str else - local function _270_(_241) + local function _271_(_241) return string.format("_%02x", _241:byte()) end - return ("__fnl_global__" .. str:gsub("[^%w]", _270_)) + return ("__fnl_global__" .. str:gsub("[^%w]", _271_)) end end local function global_unmangling(identifier) - local _272_0 = string.match(identifier, "^__fnl_global__(.*)$") - if (nil ~= _272_0) then - local rest = _272_0 - local _273_0 = nil - local function _274_(_241) + local _273_0 = string.match(identifier, "^__fnl_global__(.*)$") + if (nil ~= _273_0) then + local rest = _273_0 + local _274_0 = nil + local function _275_(_241) return string.char(tonumber(_241:sub(2), 16)) end - _273_0 = string.gsub(rest, "_[%da-f][%da-f]", _274_) - return _273_0 + _274_0 = string.gsub(rest, "_[%da-f][%da-f]", _275_) + return _274_0 else - local _ = _272_0 + local _ = _273_0 return identifier end end @@ -2349,10 +2390,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct raw = str end local mangling = nil - local function _278_(_241) + local function _279_(_241) return string.format("_%02x", _241:byte()) end - mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _278_) + mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _279_) local unique = unique_mangling(mangling, mangling, scope, 0) scope.unmanglings[unique] = (scope["gensym-base"][str] or str) do @@ -2407,29 +2448,29 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(parts, ".") end local function autogensym(base, scope) - local _282_0 = utils["multi-sym?"](base) - if (nil ~= _282_0) then - local parts = _282_0 + local _283_0 = utils["multi-sym?"](base) + if (nil ~= _283_0) then + local parts = _283_0 return combine_auto_gensym(parts, autogensym(parts[1], scope)) else - local _ = _282_0 - local function _283_() + local _ = _283_0 + local function _284_() local mangling = gensym(scope, base:sub(1, ( - 2)), "auto") scope.autogensyms[base] = mangling return mangling end - return (scope.autogensyms[base] or _283_()) + return (scope.autogensyms[base] or _284_()) end end local function check_binding_valid(symbol, scope, ast, _3fopts) local name = tostring(symbol) local macro_3f = nil do - local _285_0 = _3fopts - if (nil ~= _285_0) then - _285_0 = _285_0["macro?"] + local _286_0 = _3fopts + if (nil ~= _286_0) then + _286_0 = _286_0["macro?"] end - macro_3f = _285_0 + macro_3f = _286_0 end assert_compile(not name:find("&"), "invalid character: &", symbol) assert_compile(not name:find("^%."), "invalid character: .", symbol) @@ -2527,22 +2568,22 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function flatten_chunk(file_sourcemap, chunk, tab, depth) if chunk.leaf then - local _297_ = utils["ast-source"](chunk.ast) - local filename = _297_["filename"] - local line = _297_["line"] + local _298_ = utils["ast-source"](chunk.ast) + local filename = _298_["filename"] + local line = _298_["line"] table.insert(file_sourcemap, {filename, line}) return chunk.leaf else local tab0 = nil do - local _298_0 = tab - if (_298_0 == true) then + local _299_0 = tab + if (_299_0 == true) then tab0 = " " - elseif (_298_0 == false) then + elseif (_299_0 == false) then tab0 = "" - elseif (_298_0 == tab) then + elseif (_299_0 == tab) then tab0 = tab - elseif (_298_0 == nil) then + elseif (_299_0 == nil) then tab0 = "" else tab0 = nil @@ -2588,7 +2629,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function make_metadata() - local function _306_(self, tgt, _3fkey) + local function _307_(self, tgt, _3fkey) if self[tgt] then if (nil ~= _3fkey) then return self[tgt][_3fkey] @@ -2597,12 +2638,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end end - local function _309_(self, tgt, key, value) + local function _310_(self, tgt, key, value) self[tgt] = (self[tgt] or {}) self[tgt][key] = value return tgt end - local function _310_(self, tgt, ...) + local function _311_(self, tgt, ...) local kv_len = select("#", ...) local kvs = {...} if ((kv_len % 2) ~= 0) then @@ -2614,7 +2655,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return tgt end - return setmetatable({}, {__index = {get = _306_, set = _309_, setall = _310_}, __mode = "k"}) + return setmetatable({}, {__index = {get = _307_, set = _310_, setall = _311_}, __mode = "k"}) end local function exprs1(exprs) return table.concat(utils.map(exprs, tostring), ", ") @@ -2660,14 +2701,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end if opts.target then local result = exprs1(exprs) - local function _318_() + local function _319_() if (result == "") then return "nil" else return result end end - emit(parent, string.format("%s = %s", opts.target, _318_()), ast) + emit(parent, string.format("%s = %s", opts.target, _319_()), ast) end if (opts.tail or opts.target) then return {returned = true} @@ -2679,16 +2720,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function find_macro(ast, scope) local macro_2a = nil do - local _321_0 = utils["sym?"](ast[1]) - if (_321_0 ~= nil) then - local _322_0 = tostring(_321_0) - if (_322_0 ~= nil) then - macro_2a = scope.macros[_322_0] + local _322_0 = utils["sym?"](ast[1]) + if (_322_0 ~= nil) then + local _323_0 = tostring(_322_0) + if (_323_0 ~= nil) then + macro_2a = scope.macros[_323_0] else - macro_2a = _322_0 + macro_2a = _323_0 end else - macro_2a = _321_0 + macro_2a = _322_0 end end local multi_sym_parts = utils["multi-sym?"](ast[1]) @@ -2700,12 +2741,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macro_2a end end - local function propagate_trace_info(_326_0, _index, node) - local _327_ = _326_0 - local byteend = _327_["byteend"] - local bytestart = _327_["bytestart"] - local filename = _327_["filename"] - local line = _327_["line"] + local function propagate_trace_info(_327_0, _index, node) + local _328_ = _327_0 + local byteend = _328_["byteend"] + local bytestart = _328_["bytestart"] + local filename = _328_["filename"] + local line = _328_["line"] do local src = utils["ast-source"](node) if (("table" == type(node)) and (filename ~= src.filename)) then @@ -2718,8 +2759,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function quote_literal_nils(index, node, parent) if (parent and utils["list?"](parent)) then for i = 1, utils.maxn(parent) do - local _329_0 = parent[i] - if (_329_0 == nil) then + local _330_0 = parent[i] + if (_330_0 == nil) then parent[i] = utils.sym("nil") end end @@ -2727,10 +2768,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return index, node, parent end local function comp(f, g) - local function _332_(...) + local function _333_(...) return f(g(...)) end - return _332_ + return _333_ end local function built_in_3f(m) local found_3f = false @@ -2741,36 +2782,36 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return found_3f end local function macroexpand_2a(ast, scope, _3fonce) - local _333_0 = nil + local _334_0 = nil if utils["list?"](ast) then - _333_0 = find_macro(ast, scope) + _334_0 = find_macro(ast, scope) else - _333_0 = nil + _334_0 = nil end - if (_333_0 == false) then + if (_334_0 == false) then return ast - elseif (nil ~= _333_0) then - local macro_2a = _333_0 + elseif (nil ~= _334_0) then + local macro_2a = _334_0 local old_scope = scopes.macro local _ = nil scopes.macro = scope _ = nil local ok, transformed = nil, nil - local function _335_() + local function _336_() return macro_2a(unpack(ast, 2)) end - local function _336_() + local function _337_() if built_in_3f(macro_2a) then return tostring else return debug.traceback end end - ok, transformed = xpcall(_335_, _336_()) - local function _337_(...) + ok, transformed = xpcall(_336_, _337_()) + local function _338_(...) return propagate_trace_info(ast, ...) end - utils["walk-tree"](transformed, comp(_337_, quote_literal_nils)) + utils["walk-tree"](transformed, comp(_338_, quote_literal_nils)) scopes.macro = old_scope assert_compile(ok, transformed, ast) if (_3fonce or not transformed) then @@ -2779,7 +2820,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macroexpand_2a(transformed, scope) end else - local _ = _333_0 + local _ = _334_0 return ast end end @@ -2811,13 +2852,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile((utils["sym?"](ast[1]) or utils["list?"](ast[1]) or ("string" == type(ast[1]))), ("cannot call literal value " .. tostring(ast[1])), ast) for i = 2, len do local subexprs = nil - local _343_ + local _344_ if (i ~= len) then - _343_ = 1 + _344_ = 1 else - _343_ = nil + _344_ = nil end - subexprs = compile1(ast[i], scope, parent, {nval = _343_}) + subexprs = compile1(ast[i], scope, parent, {nval = _344_}) table.insert(fargs, subexprs[1]) if (i == len) then for j = 2, #subexprs do @@ -2855,13 +2896,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_varg(ast, scope, parent, opts) - local _348_ + local _349_ if scope.hashfn then - _348_ = "use $... in hashfn" + _349_ = "use $... in hashfn" else - _348_ = "unexpected vararg" + _349_ = "unexpected vararg" end - assert_compile(scope.vararg, _348_, ast) + assert_compile(scope.vararg, _349_, ast) return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast) end local function compile_sym(ast, scope, parent, opts) @@ -2876,20 +2917,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return handle_compile_opts({e}, parent, opts, ast) end local function serialize_number(n) - local _351_0 = string.gsub(tostring(n), ",", ".") - return _351_0 + local _352_0 = string.gsub(tostring(n), ",", ".") + return _352_0 end local function compile_scalar(ast, _scope, parent, opts) local serialize = nil do - local _352_0 = type(ast) - if (_352_0 == "nil") then + local _353_0 = type(ast) + if (_353_0 == "nil") then serialize = tostring - elseif (_352_0 == "boolean") then + elseif (_353_0 == "boolean") then serialize = tostring - elseif (_352_0 == "string") then + elseif (_353_0 == "string") then serialize = serialize_string - elseif (_352_0 == "number") then + elseif (_353_0 == "number") then serialize = serialize_number else serialize = nil @@ -2902,8 +2943,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if ((type(k) == "string") and utils["valid-lua-identifier?"](k)) then return k else - local _354_ = compile1(k, scope, parent, {nval = 1}) - local compiled = _354_[1] + local _355_ = compile1(k, scope, parent, {nval = 1}) + local compiled = _355_[1] return ("[" .. tostring(compiled) .. "]") end end @@ -2929,12 +2970,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct do local tbl_17_ = buffer local i_18_ = #tbl_17_ - for k, v in utils.stablepairs(ast) do + for k in utils.stablepairs(ast) do local val_19_ = nil if not keys[k] then - local _357_ = compile1(ast[k], scope, parent, {nval = 1}) - local v0 = _357_[1] - val_19_ = string.format("%s = %s", escape_key(k), tostring(v0)) + local _358_ = compile1(ast[k], scope, parent, {nval = 1}) + local v = _358_[1] + val_19_ = string.format("%s = %s", escape_key(k), tostring(v)) else val_19_ = nil end @@ -2965,12 +3006,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function destructure(to, from, ast, scope, parent, opts) local opts0 = (opts or {}) - local _361_ = opts0 - local declaration = _361_["declaration"] - local forceglobal = _361_["forceglobal"] - local forceset = _361_["forceset"] - local isvar = _361_["isvar"] - local symtype = _361_["symtype"] + local _362_ = opts0 + local declaration = _362_["declaration"] + local forceglobal = _362_["forceglobal"] + local forceset = _362_["forceset"] + local isvar = _362_["isvar"] + local symtype = _362_["symtype"] local symtype0 = ("_" .. (symtype or "dst")) local setter = nil if declaration then @@ -2986,8 +3027,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return declare_local(symbol, nil, scope, symbol, new_manglings) else local parts = (utils["multi-sym?"](raw) or {raw}) - local _363_ = parts - local first = _363_[1] + local _364_ = parts + local first = _364_[1] local meta = scope.symmeta[first] assert_compile(not raw:find(":"), "cannot set method sym", symbol) if ((#parts == 1) and not forceset) then @@ -3008,14 +3049,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function compile_top_target(lvalues) local inits = nil - local function _368_(_241) + local function _369_(_241) if scope.manglings[_241] then return _241 else return "nil" end end - inits = utils.map(lvalues, _368_) + inits = utils.map(lvalues, _369_) local init = table.concat(inits, ", ") local lvalue = table.concat(lvalues, ", ") local plast = parent[#parent] @@ -3053,7 +3094,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local unpack_fn = "function (t, k, e)\n local mt = getmetatable(t)\n if 'table' == type(mt) and mt.__fennelrest then\n return mt.__fennelrest(t, k)\n elseif e then\n local rest = {}\n for k, v in pairs(t) do\n if not e[k] then rest[k] = v end\n end\n return rest\n else\n return {(table.unpack or unpack)(t, k)}\n end\n end" local function destructure_kv_rest(s, v, left, excluded_keys, destructure1) local exclude_str = nil - local _375_ + local _376_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3064,9 +3105,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _375_ = tbl_17_ + _376_ = tbl_17_ end - exclude_str = table.concat(_375_, ", ") + exclude_str = table.concat(_376_, ", ") local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_fn .. ")(%s, %s, {%s})"), "\n%s*", " "), s, tostring(v), exclude_str), "expression") return destructure1(v, {subexpr}, left) end @@ -3081,16 +3122,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local s = gensym(scope, symtype0) local right = nil do - local _377_0 = nil + local _378_0 = nil if top_3f then - _377_0 = exprs1(compile1(from, scope, parent)) + _378_0 = exprs1(compile1(from, scope, parent)) else - _377_0 = exprs1(rightexprs) + _378_0 = exprs1(rightexprs) end - if (_377_0 == "") then + if (_378_0 == "") then right = "nil" - elseif (nil ~= _377_0) then - local right0 = _377_0 + elseif (nil ~= _378_0) then + local right0 = _378_0 right = right0 else right = nil @@ -3195,8 +3236,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if opts.requireAsInclude then scope.specials.require = require_include end - local _391_ = utils.root - _391_["set-reset"](_391_) + if opts.assertAsRepl then + scope.macros.assert = scope.macros["assert-repl"] + end + local _393_ = utils.root + _393_["set-reset"](_393_) utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts for i = 1, #asts do local exprs = compile1(asts[i], scope, chunk, {nval = (((i < #asts) and 0) or nil), tail = (i == #asts)}) @@ -3247,14 +3291,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct info.currentline = (remap[info.currentline][2] or -1) end if (info.what == "Lua") then - local function _396_() + local function _398_() if info.name then return ("'" .. info.name .. "'") else return "?" end end - return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _396_()) + return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _398_()) elseif (info.short_src == "(tail call)") then return " (tail call)" else @@ -3278,11 +3322,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local done_3f, level = false, (_3fstart or 2) while not done_3f do do - local _400_0 = debug.getinfo(level, "Sln") - if (_400_0 == nil) then + local _402_0 = debug.getinfo(level, "Sln") + if (_402_0 == nil) then done_3f = true - elseif (nil ~= _400_0) then - local info = _400_0 + elseif (nil ~= _402_0) then + local info = _402_0 table.insert(lines, traceback_frame(info)) end end @@ -3292,14 +3336,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function entry_transform(fk, fv) - local function _403_(k, v) + local function _405_(k, v) if (type(k) == "number") then return k, fv(v) else return fk(k), fv(v) end end - return _403_ + return _405_ end local function mixed_concat(t, joiner) local seen = {} @@ -3344,10 +3388,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return res[1] elseif utils["list?"](form) then local mapped = nil - local function _408_() + local function _410_() return nil end - mapped = utils.kvmap(form, entry_transform(_408_, q)) + mapped = utils.kvmap(form, entry_transform(_410_, q)) local filename = nil if form.filename then filename = string.format("%q", form.filename) @@ -3365,13 +3409,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local _411_ + local _413_ if source then - _411_ = source.line + _413_ = source.line else - _411_ = "nil" + _413_ = "nil" end - return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _411_, "(getmetatable(sequence()))['sequence']") + return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _413_, "(getmetatable(sequence()))['sequence']") elseif (type(form) == "table") then local mapped = utils.kvmap(form, entry_transform(q, q)) local source = getmetatable(form) @@ -3381,14 +3425,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local function _414_() + local function _416_() if source then return source.line else return "nil" end end - return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _414_()) + return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _416_()) elseif (type(form) == "string") then return serialize_string(form) else @@ -3610,7 +3654,9 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( else r = getbyte({["stack-size"] = #stack}) end - byteindex = (byteindex + 1) + if r then + byteindex = (byteindex + 1) + end if (r and char_starter_3f(r)) then col = (col + 1) end @@ -3620,14 +3666,14 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return r end local function whitespace_3f(b) - local function _216_() - local _215_0 = options.whitespace - if (nil ~= _215_0) then - _215_0 = _215_0[b] + local function _217_() + local _216_0 = options.whitespace + if (nil ~= _216_0) then + _216_0 = _216_0[b] end - return _215_0 + return _216_0 end - return ((b == 32) or ((9 <= b) and (b <= 13)) or _216_()) + return ((b == 32) or ((9 <= b) and (b <= 13)) or _217_()) end local function parse_error(msg, _3fcol_adjust) local col0 = (col + (_3fcol_adjust or -1)) @@ -3647,25 +3693,25 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return nil end local function dispatch(v) - local _220_0 = stack[#stack] - if (_220_0 == nil) then + local _221_0 = stack[#stack] + if (_221_0 == nil) then retval, done_3f, whitespace_since_dispatch = v, true, false return nil - elseif ((_G.type(_220_0) == "table") and (nil ~= _220_0.prefix)) then - local prefix = _220_0.prefix + elseif ((_G.type(_221_0) == "table") and (nil ~= _221_0.prefix)) then + local prefix = _221_0.prefix local source0 = nil do - local _221_0 = table.remove(stack) - set_source_fields(_221_0) - source0 = _221_0 + local _222_0 = table.remove(stack) + set_source_fields(_222_0) + source0 = _222_0 end local list = utils.list(utils.sym(prefix, source0), v) for k, v0 in pairs(source0) do list[k] = v0 end return dispatch(list) - elseif (nil ~= _220_0) then - local top = _220_0 + elseif (nil ~= _221_0) then + local top = _221_0 whitespace_since_dispatch = false return table.insert(top, v) end @@ -3673,13 +3719,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( local close_table = nil local function badend(cause) local accum = utils.map(stack, "closer") - local _223_ + local _224_ if (#stack == 1) then - _223_ = "" + _224_ = "" else - _223_ = "s" + _224_ = "s" end - parse_error(string.format("expected closing delimiter%s %s", _223_, string.char(unpack(accum)))) + parse_error(string.format("expected closing delimiter%s %s", _224_, string.char(unpack(accum)))) if (cause == "eof") then for i = #accum, 2, -1 do close_table(accum[i]) @@ -3699,11 +3745,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local function parse_comment(b, contents) if (b and (10 ~= b)) then - local function _227_() + local function _228_() table.insert(contents, string.char(b)) return contents end - return parse_comment(getb(), _227_()) + return parse_comment(getb(), _228_()) elseif comments then ungetb(10) return dispatch(utils.comment(table.concat(contents), {filename = filename, line = line})) @@ -3729,12 +3775,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( return dispatch(setmetatable(tbl, mt)) end local function add_comment_at(comments0, index, node) - local _231_0 = comments0[index] - if (nil ~= _231_0) then - local existing = _231_0 + local _232_0 = comments0[index] + if (nil ~= _232_0) then + local existing = _232_0 return table.insert(existing, node) else - local _ = _231_0 + local _ = _232_0 comments0[index] = {node} return nil end @@ -3814,16 +3860,16 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local state0 = nil do - local _242_0 = {state, b} - if ((_G.type(_242_0) == "table") and (_242_0[1] == "base") and (_242_0[2] == 92)) then + local _243_0 = {state, b} + if ((_G.type(_243_0) == "table") and (_243_0[1] == "base") and (_243_0[2] == 92)) then state0 = "backslash" - elseif ((_G.type(_242_0) == "table") and (_242_0[1] == "base") and (_242_0[2] == 34)) then + elseif ((_G.type(_243_0) == "table") and (_243_0[1] == "base") and (_243_0[2] == 34)) then state0 = "done" - elseif ((_G.type(_242_0) == "table") and (_242_0[1] == "backslash") and (_242_0[2] == 10)) then + elseif ((_G.type(_243_0) == "table") and (_243_0[1] == "backslash") and (_243_0[2] == 10)) then table.remove(chars, (#chars - 1)) state0 = "base" else - local _ = _242_0 + local _ = _243_0 state0 = "base" end end @@ -3845,11 +3891,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( table.remove(stack) local raw = table.concat(chars) local formatted = raw:gsub("[\7-\13]", escape_char) - local _246_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) - if (nil ~= _246_0) then - local load_fn = _246_0 + local _247_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) + if (nil ~= _247_0) then + local load_fn = _247_0 return dispatch(load_fn()) - elseif (_246_0 == nil) then + elseif (_247_0 == nil) then return parse_error(("Invalid string: " .. raw)) end end @@ -3882,13 +3928,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( dispatch((tonumber(number_with_stripped_underscores) or parse_error(("could not read number \"" .. rawstr .. "\"")))) return true else - local _252_0 = tonumber(number_with_stripped_underscores) - if (nil ~= _252_0) then - local x = _252_0 + local _253_0 = tonumber(number_with_stripped_underscores) + if (nil ~= _253_0) then + local x = _253_0 dispatch(x) return true else - local _ = _252_0 + local _ = _253_0 return false end end @@ -3935,7 +3981,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( elseif delims[b] then close_table0(b) elseif (b == 34) then - parse_string(b) + parse_string() elseif prefixes[b] then parse_prefix(b) elseif (sym_char_3f(b) or (b == string.byte("~"))) then @@ -3953,11 +3999,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return parse_loop(skip_whitespace(getb())) end - local function _259_() + local function _260_() stack, line, byteindex, col, lastb = {}, 1, 0, 0, nil return nil end - return parse_stream, _259_ + return parse_stream, _260_ end local function parser(stream_or_string, _3ffilename, _3foptions) local filename = (_3ffilename or "unknown") @@ -4590,7 +4636,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(...) local view = require("fennel.view") - local version = "1.3.2-dev" + local version = "1.4.0-dev" local function luajit_vm_3f() return ((nil ~= _G.jit) and (type(_G.jit) == "table") and (nil ~= _G.jit.on) and (nil ~= _G.jit.off) and (type(_G.jit.version_num) == "number")) end @@ -5058,7 +5104,8 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return symbol.quoted end local function idempotent_expr_3f(x) - return ((type(x) == "string") or (type(x) == "integer") or (type(x) == "number") or (sym_3f(x) and not multi_sym_3f(x))) + local t = type(x) + return ((t == "string") or (t == "integer") or (t == "number") or (t == "boolean") or (sym_3f(x) and not multi_sym_3f(x))) end local function ast_source(ast) if (table_3f(ast) or sequence_3f(ast)) then @@ -5192,14 +5239,14 @@ local function eval(str, _3foptions, ...) local env = eval_env(opts.env, opts) local lua_source = compiler["compile-string"](str, opts) local loader = nil - local function _735_(...) + local function _746_(...) if opts.filename then return ("@" .. opts.filename) else return str end end - loader = specials["load-code"](lua_source, env, _735_(...)) + loader = specials["load-code"](lua_source, env, _746_(...)) opts.filename = nil return loader(...) end @@ -5224,10 +5271,10 @@ local function syntax() out[k] = {["binding-form?"] = utils["member?"](k, binding_3f), ["body-form?"] = utils["member?"](k, body_3f), ["define?"] = utils["member?"](k, define_3f), ["macro?"] = true} end for k, v in pairs(_G) do - local _736_0 = type(v) - if (_736_0 == "function") then + local _747_0 = type(v) + if (_747_0 == "function") then out[k] = {["function?"] = true, ["global?"] = true} - elseif (_736_0 == "table") then + elseif (_747_0 == "table") then for k2, v2 in pairs(v) do if (("function" == type(v2)) and (k ~= "_G")) then out[(k .. "." .. k2)] = {["function?"] = true, ["global?"] = true} @@ -5247,19 +5294,21 @@ utils["fennel-module"] = mod do local module_name = "fennel.macros" local _ = nil - local function _739_() + local function _750_() return mod end - package.preload[module_name] = _739_ + package.preload[module_name] = _750_ _ = nil local env = nil do - local _740_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) - _740_0["utils"] = utils - _740_0["fennel"] = mod - env = _740_0 + local _751_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) + _751_0["utils"] = utils + _751_0["fennel"] = mod + env = _751_0 end - local built_ins = eval([===[;; These macros are awkward because their definition cannot rely on the any + local built_ins = eval([===[;; fennel-ls: macro-file + + ;; These macros are awkward because their definition cannot rely on the any ;; built-in macros, only special forms. (no when, no icollect, etc) (fn copy [t] @@ -5382,7 +5431,7 @@ do (table.remove iter-out i))))) (assert (or (not found?) (sym? into) (table? into) (list? into)) "expected table, function call, or symbol in &into clause") - (values into iter-out)) + (values into iter-out found?)) (fn collect* [iter-tbl key-expr value-expr ...] "Return a table made by running an iterator and evaluating an expression that @@ -5420,17 +5469,22 @@ do (assert (not= nil value-expr) "expected table value expression") (assert (= nil ...) "expected exactly one body expression. Wrap multiple expressions in do") - (let [(into iter) (extract-into iter-tbl)] - `(let [tbl# ,into] - ;; believe it or not, using a var here has a pretty good performance - ;; boost: https://p.hagelb.org/icollect-performance.html - (var i# (length tbl#)) - (,how ,iter - (let [val# ,value-expr] - (when (not= nil val#) - (set i# (+ i# 1)) - (tset tbl# i# val#)))) - tbl#))) + (let [(into iter has-into?) (extract-into iter-tbl)] + (if has-into? + `(let [tbl# ,into] + (,how ,iter (table.insert tbl# ,value-expr)) + tbl#) + ;; believe it or not, using a var here has a pretty good performance + ;; boost: https://p.hagelb.org/icollect-performance.html + ;; but it doesn't always work with &into clauses, so skip if that's used + `(let [tbl# []] + (var i# 0) + (,how ,iter + (let [val# ,value-expr] + (when (not= nil val#) + (set i# (+ i# 1)) + (tset tbl# i# val#)))) + tbl#)))) (fn icollect* [iter-tbl value-expr ...] "Return a sequential table made by running an iterator and evaluating an @@ -5564,7 +5618,7 @@ do (.. "Expected n to be an integer >= 0, got " (tostring n))) (let [let-syms (list) let-values (if (= 1 (select "#" ...)) ... `(values ,...))] - (for [i 1 n] + (for [_ 1 n] (table.insert let-syms (gensym))) (if (= n 0) `(values) `(let [,let-syms ,let-values] @@ -5649,6 +5703,30 @@ do (tset scope.macros import-key (. macros* macro-name)))))) nil) + (fn assert-repl* [condition message ?opts] + "Drop into a debug repl and print the message when condition is false/nil. + Takes an optional table of arguments which will be passed to fennel.repl." + (fn add-locals [{: symmeta : parent} locals] + (each [name (pairs symmeta)] + (tset locals name (sym name))) + (if parent (add-locals parent locals) locals)) + `(let [condition# ,condition + message# (or ,message "assertion failed, entering repl.")] + (if (not condition#) + (let [opts# (or ,?opts {:assert-repl? true + :readChunk (?. _G :___repl___ :readChunk) + :onError (?. _G :___repl___ :onError) + :onValued (?. _G :___repl___ :onValued)}) + fennel# (require (or opts#.moduleName :fennel)) + locals# ,(add-locals (get-scope) [])] + (set opts#.message (fennel#.traceback message#)) + (set opts#.env (collect [k# v# (pairs _G) &into locals#] + (if (= nil (. locals# k#)) (values k# v#)))) + (_G.assert (fennel#.repl opts#) message#)) + ;; `assert` returns *all* params on success, but omitting opts# to + ;; defensively prevent accidental leakage of REPL opts into code + (values condition# message#)))) + {:-> ->* :->> ->>* :-?> -?>* @@ -5669,14 +5747,17 @@ do :pick-values pick-values* :macro macro* :macrodebug macrodebug* - :import-macros import-macros*} + :import-macros import-macros* + :assert-repl assert-repl*} ]===], {env = env, filename = "src/fennel/macros.fnl", moduleName = module_name, scope = compiler.scopes.compiler, useMetadata = true}) local _0 = nil for k, v in pairs(built_ins) do compiler.scopes.global.macros[k] = v end _0 = nil - local match_macros = eval([===[;;; Pattern matching + local match_macros = eval([===[;; fennel-ls: macro-file + + ;;; Pattern matching ;; This is separated out so we can use the "core" macros during the ;; implementation of pattern matching. @@ -5779,7 +5860,7 @@ do (let [in-pattern (symbols-in-pattern pattern)] (if ?symbols (do - (each [name symbol (pairs ?symbols)] + (each [name (pairs ?symbols)] (when (not (. in-pattern name)) (tset ?symbols name nil))) ?symbols) @@ -5795,7 +5876,7 @@ do (if (= 0 (length bindings)) ;; no bindings special case generates simple code (let [condition - (icollect [i subpattern (ipairs pattern) &into `(or)] + (icollect [_ subpattern (ipairs pattern) &into `(or)] (let [(subcondition subbindings) (case-pattern vals subpattern unifications opts)] subcondition))] (values @@ -5808,7 +5889,7 @@ do bindings-mangled (icollect [_ binding (ipairs bindings)] (gensym (tostring binding))) pre-bindings `(if)] - (each [i subpattern (ipairs pattern)] + (each [_ subpattern (ipairs pattern)] (let [(subcondition subbindings) (case-guard vals subpattern guards {} case-pattern opts)] (table.insert pre-bindings subcondition) (table.insert pre-bindings `(let ,subbindings @@ -5974,7 +6055,7 @@ do (case-condition (list val) clauses match?) ;; protect against multiple evaluation of the value, bind against as ;; many values as we ever match against in the clauses. - (let [vals (fcollect [i 1 vals-count &into (list)] (gensym))] + (let [vals (fcollect [_ 1 vals-count &into (list)] (gensym))] (list `let [vals val] (case-condition vals clauses match?)))))) (fn case* [val ...]