From 2edb9c4df5300ff4f7f1d5e23607f6c021151fb6 Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Sun, 16 Feb 2025 17:06:22 -0800 Subject: [PATCH] Update to fennel 1.5.3 --- changelog.md | 5 +- deps/fennel.lua | 3579 ++++++++++++++++----------------- docs/manual.md | 4 +- fennel | 3824 ++++++++++++++++++------------------ src/fennel-ls/compiler.fnl | 2 +- 5 files changed, 3752 insertions(+), 3662 deletions(-) diff --git a/changelog.md b/changelog.md index 52024ba..d284c08 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,7 @@ # Changelog +## UNRELEASED + ### Features * Settings file: `flsproject.fnl`. Settings are now editor agnostic. @@ -7,9 +9,6 @@ * (set (. x y) z) wasn't being analyzed properly. * (local {: unknown-field} (require :module)) lint warns about the unknown field when accessed via destructuring. -### Changes -* Test code has been refactored - ## 0.1.3 ### Features diff --git a/deps/fennel.lua b/deps/fennel.lua index 13a8c73..975525f 100644 --- a/deps/fennel.lua +++ b/deps/fennel.lua @@ -1,7 +1,9 @@ -- 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 _710_ = require("fennel.utils") + local utils = _710_ + local copy = _710_["copy"] local parser = require("fennel.parser") local compiler = require("fennel.compiler") local specials = require("fennel.specials") @@ -17,24 +19,27 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) 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")) + local _712_0 = io.read() + if (nil ~= _712_0) then + local input = _712_0 + return (input .. "\n") + end end local function default_on_values(xs) io.write(table.concat(xs, "\9")) return io.write("\n") end local function default_on_error(errtype, err) - local function _702_() - local _701_0 = errtype - if (_701_0 == "Runtime") then + local function _715_() + local _714_0 = errtype + if (_714_0 == "Runtime") then return (compiler.traceback(tostring(err), 4) .. "\n") else - local _ = _701_0 + local _ = _714_0 return ("%s error: %s\n"):format(errtype, tostring(err)) end end - return io.write(_702_()) + return io.write(_715_()) end local function splice_save_locals(env, lua_source, scope) local saves = nil @@ -74,25 +79,25 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) else gap = " " end - local function _708_() + local function _721_() if next(saves) then return (table.concat(saves, " ") .. gap) else return "" end end - local function _711_() - local _709_0, _710_0 = lua_source:match("^(.*)[\n ](return .*)$") - if ((nil ~= _709_0) and (nil ~= _710_0)) then - local body = _709_0 - local _return = _710_0 + local function _724_() + local _722_0, _723_0 = lua_source:match("^(.*)[\n ](return .*)$") + if ((nil ~= _722_0) and (nil ~= _723_0)) then + local body = _722_0 + local _return = _723_0 return (body .. gap .. table.concat(binds, " ") .. gap .. _return) else - local _ = _709_0 + local _ = _722_0 return lua_source end end - return (_708_() .. _711_()) + return (_721_() .. _724_()) end local commands = {} local function completer(env, scope, text, _3ffulltext, _from, _to) @@ -105,14 +110,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 _713_() + local function _726_() if scope_first_3f then return scope.manglings else return tbl end end - for k, is_mangled in utils.allpairs(_713_()) do + for k, is_mangled in utils.allpairs(_726_()) do if (max_items <= #matches) then break end local val_19_ = nil do @@ -170,12 +175,12 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end end do - local _722_0 = tostring((_3ffulltext or text)):match("^%s*,([^%s()[%]]*)$") - if (nil ~= _722_0) then - local cmd_fragment = _722_0 + local _735_0 = tostring((_3ffulltext or text)):match("^%s*,([^%s()[%]]*)$") + if (nil ~= _735_0) then + local cmd_fragment = _735_0 add_partials(cmd_fragment, commands, ",") else - local _ = _722_0 + local _ = _735_0 for _0, source in ipairs({scope.specials, scope.macros, (env.___replLocals___ or {}), env, env._G}) do if stop_looking_3f then break end add_matches(input_fragment, source) @@ -188,7 +193,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return input:match("^%s*,") end local function command_docs() - local _724_ + local _737_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -199,30 +204,30 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) tbl_17_[i_18_] = val_19_ end end - _724_ = tbl_17_ + _737_ = tbl_17_ end - return table.concat(_724_, "\n") + return table.concat(_737_, "\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 ,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 _726_0, _727_0 = pcall(specials["load-code"]("return require(...)", env), module_name) - if ((_726_0 == true) and (nil ~= _727_0)) then - local old = _727_0 + local _739_0, _740_0 = pcall(specials["load-code"]("return require(...)", env), module_name) + if ((_739_0 == true) and (nil ~= _740_0)) then + local old = _740_0 local _ = nil package.loaded[module_name] = nil _ = nil local new = nil do - local _728_0, _729_0 = pcall(require, module_name) - if ((_728_0 == true) and (nil ~= _729_0)) then - local new0 = _729_0 + local _741_0, _742_0 = pcall(require, module_name) + if ((_741_0 == true) and (nil ~= _742_0)) then + local new0 = _742_0 new = new0 - elseif (true and (nil ~= _729_0)) then - local _0 = _728_0 - local msg = _729_0 + elseif (true and (nil ~= _742_0)) then + local _0 = _741_0 + local msg = _742_0 on_error("Repl", msg) new = old else @@ -242,8 +247,8 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) package.loaded[module_name] = old end return on_values({"ok"}) - elseif ((_726_0 == false) and (nil ~= _727_0)) then - local msg = _727_0 + elseif ((_739_0 == false) and (nil ~= _740_0)) then + local msg = _740_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) @@ -251,32 +256,32 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) specials["macro-loaded"][module_name] = nil return nil else - local function _734_() - local _733_0 = msg:gsub("\n.*", "") - return _733_0 + local function _747_() + local _746_0 = msg:gsub("\n.*", "") + return _746_0 end - return on_error("Runtime", _734_()) + return on_error("Runtime", _747_()) end end end local function run_command(read, on_error, f) - local _737_0, _738_0, _739_0 = pcall(read) - if ((_737_0 == true) and (_738_0 == true) and (nil ~= _739_0)) then - local val = _739_0 - local _740_0, _741_0 = pcall(f, val) - if ((_740_0 == false) and (nil ~= _741_0)) then - local msg = _741_0 + local _750_0, _751_0, _752_0 = pcall(read) + if ((_750_0 == true) and (_751_0 == true) and (nil ~= _752_0)) then + local val = _752_0 + local _753_0, _754_0 = pcall(f, val) + if ((_753_0 == false) and (nil ~= _754_0)) then + local msg = _754_0 return on_error("Runtime", msg) end - elseif (_737_0 == false) then + elseif (_750_0 == false) then return on_error("Parse", "Couldn't parse input.") end end commands.reload = function(env, read, on_values, on_error) - local function _744_(_241) + local function _757_(_241) return reload(tostring(_241), env, on_values, on_error) end - return run_command(read, on_error, _744_) + return run_command(read, on_error, _757_) end do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.") commands.reset = function(env, _, on_values) @@ -285,28 +290,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 _745_() + local function _758_() return on_values(completer(env, scope, table.concat(chars):gsub("^%s*,complete%s+", ""):sub(1, -2))) end - return run_command(read, on_error, _745_) + return run_command(read, on_error, _758_) 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 _746_0 = type(subtbl) - if (_746_0 == "function") then + local _759_0 = type(subtbl) + if (_759_0 == "function") then if ((prefix .. name)):match(pattern) then table.insert(names, (prefix .. name)) end - elseif (_746_0 == "table") then + elseif (_759_0 == "table") then if not seen[subtbl] then - local _748_ + local _761_ do seen[subtbl] = true - _748_ = seen + _761_ = seen end - apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _748_, names) + apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _761_, names) end end end @@ -317,10 +322,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return apropos_2a(pattern:gsub("^_G%.", ""), package.loaded, "", {}, {}) end commands.apropos = function(_env, read, on_values, on_error, _scope) - local function _752_(_241) + local function _765_(_241) return on_values(apropos(tostring(_241))) end - return run_command(read, on_error, _752_) + return run_command(read, on_error, _765_) 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) @@ -340,12 +345,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 _755_ + local _768_ do - local _754_0 = path0:gsub("%/", ".") - _755_ = _754_0 + local _767_0 = path0:gsub("%/", ".") + _768_ = _767_0 end - tgt = tgt[_755_] + tgt = tgt[_768_] end return tgt end @@ -357,9 +362,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) do local tgt = apropos_follow_path(path) if ("function" == type(tgt)) then - local _756_0 = (compiler.metadata):get(tgt, "fnl/docstring") - if (nil ~= _756_0) then - local docstr = _756_0 + local _769_0 = (compiler.metadata):get(tgt, "fnl/docstring") + if (nil ~= _769_0) then + local docstr = _769_0 val_19_ = (docstr:match(pattern) and path) else val_19_ = nil @@ -376,10 +381,10 @@ 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 _760_(_241) + local function _773_(_241) return on_values(apropos_doc(tostring(_241))) end - return run_command(read, on_error, _760_) + return run_command(read, on_error, _773_) 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) @@ -393,127 +398,127 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return nil end commands["apropos-show-docs"] = function(_env, read, on_values, on_error) - local function _762_(_241) + local function _775_(_241) return apropos_show_docs(on_values, tostring(_241)) end - return run_command(read, on_error, _762_) + return run_command(read, on_error, _775_) 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, _763_0, scope) - local _764_ = _763_0 - local env = _764_ - local ___replLocals___ = _764_["___replLocals___"] + local function resolve(identifier, _776_0, scope) + local _777_ = _776_0 + local env = _777_ + local ___replLocals___ = _777_["___replLocals___"] local e = nil - local function _765_(_241, _242) + local function _778_(_241, _242) return (___replLocals___[scope.unmanglings[_242]] or env[_242]) end - e = setmetatable({}, {__index = _765_}) - local function _766_(...) - local _767_0, _768_0 = ... - if ((_767_0 == true) and (nil ~= _768_0)) then - local code = _768_0 - local function _769_(...) - local _770_0, _771_0 = ... - if ((_770_0 == true) and (nil ~= _771_0)) then - local val = _771_0 + e = setmetatable({}, {__index = _778_}) + local function _779_(...) + local _780_0, _781_0 = ... + if ((_780_0 == true) and (nil ~= _781_0)) then + local code = _781_0 + local function _782_(...) + local _783_0, _784_0 = ... + if ((_783_0 == true) and (nil ~= _784_0)) then + local val = _784_0 return val else - local _ = _770_0 + local _ = _783_0 return nil end end - return _769_(pcall(specials["load-code"](code, e))) + return _782_(pcall(specials["load-code"](code, e))) else - local _ = _767_0 + local _ = _780_0 return nil end end - return _766_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) + return _779_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) end commands.find = function(env, read, on_values, on_error, scope) - local function _774_(_241) - local _775_0 = nil + local function _787_(_241) + local _788_0 = nil do - local _776_0 = utils["sym?"](_241) - if (nil ~= _776_0) then - local _777_0 = resolve(_776_0, env, scope) - if (nil ~= _777_0) then - _775_0 = debug.getinfo(_777_0) + local _789_0 = utils["sym?"](_241) + if (nil ~= _789_0) then + local _790_0 = resolve(_789_0, env, scope) + if (nil ~= _790_0) then + _788_0 = debug.getinfo(_790_0) else - _775_0 = _777_0 + _788_0 = _790_0 end else - _775_0 = _776_0 + _788_0 = _789_0 end end - if ((_G.type(_775_0) == "table") and (nil ~= _775_0.linedefined) and (nil ~= _775_0.short_src) and (nil ~= _775_0.source) and (_775_0.what == "Lua")) then - local line = _775_0.linedefined - local src = _775_0.short_src - local source = _775_0.source + if ((_G.type(_788_0) == "table") and (nil ~= _788_0.linedefined) and (nil ~= _788_0.short_src) and (nil ~= _788_0.source) and (_788_0.what == "Lua")) then + local line = _788_0.linedefined + local src = _788_0.short_src + local source = _788_0.source local fnlsrc = nil do - local _780_0 = compiler.sourcemap - if (nil ~= _780_0) then - _780_0 = _780_0[source] + local _793_0 = compiler.sourcemap + if (nil ~= _793_0) then + _793_0 = _793_0[source] end - if (nil ~= _780_0) then - _780_0 = _780_0[line] + if (nil ~= _793_0) then + _793_0 = _793_0[line] end - if (nil ~= _780_0) then - _780_0 = _780_0[2] + if (nil ~= _793_0) then + _793_0 = _793_0[2] end - fnlsrc = _780_0 + fnlsrc = _793_0 end return on_values({string.format("%s:%s", src, (fnlsrc or line))}) - elseif (_775_0 == nil) then + elseif (_788_0 == nil) then return on_error("Repl", "Unknown value") else - local _ = _775_0 + local _ = _788_0 return on_error("Repl", "No source info") end end - return run_command(read, on_error, _774_) + return run_command(read, on_error, _787_) 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 _785_(_241) + local function _798_(_241) local name = tostring(_241) local path = (utils["multi-sym?"](name) or {name}) local ok_3f, target = nil, nil - local function _786_() + local function _799_() return (scope.specials[name] or utils["get-in"](scope.macros, path) or resolve(name, env, scope)) end - ok_3f, target = pcall(_786_) + ok_3f, target = pcall(_799_) 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, _785_) + return run_command(read, on_error, _798_) 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(_, read, on_values, on_error, _0, _1, opts) - local function _788_(_241) - local _789_0, _790_0 = pcall(compiler.compile, _241, opts) - if ((_789_0 == true) and (nil ~= _790_0)) then - local result = _790_0 + local function _801_(_241) + local _802_0, _803_0 = pcall(compiler.compile, _241, opts) + if ((_802_0 == true) and (nil ~= _803_0)) then + local result = _803_0 return on_values({result}) - elseif (true and (nil ~= _790_0)) then - local _2 = _789_0 - local msg = _790_0 + elseif (true and (nil ~= _803_0)) then + local _2 = _802_0 + local msg = _803_0 return on_error("Repl", ("Error compiling expression: " .. msg)) end end - return run_command(read, on_error, _788_) + return run_command(read, on_error, _801_) 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 _792_0 = name:match("^repl%-command%-(.*)") - if (nil ~= _792_0) then - local cmd_name = _792_0 + local _805_0 = name:match("^repl%-command%-(.*)") + if (nil ~= _805_0) then + local cmd_name = _805_0 commands[cmd_name] = f end end @@ -523,12 +528,12 @@ 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, opts) local command_name = input:match(",([^%s/]+)") do - local _794_0 = commands[command_name] - if (nil ~= _794_0) then - local command = _794_0 + local _807_0 = commands[command_name] + if (nil ~= _807_0) then + local command = _807_0 command(env, read, on_values, on_error, scope, chars, opts) else - local _ = _794_0 + local _ = _807_0 if ((command_name ~= "exit") and (command_name ~= "return")) then on_values({"Unknown command", command_name}) end @@ -545,15 +550,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end readline.set_options({histfile = "", keeplines = 1000}) opts.readChunk = function(parser_state) - local prompt = nil - if (0 < parser_state["stack-size"]) then - prompt = ".. " - else - prompt = ">> " - end - local str = readline.readline(prompt) - if str then - return (str .. "\n") + local _812_0 = readline.readline(prompt_for((0 == parser_state["stack-size"]))) + if (nil ~= _812_0) then + local input = _812_0 + return (input .. "\n") end end local completer0 = nil @@ -578,9 +578,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end local function repl(_3foptions) local old_root_options = utils.root.options - local _803_ = utils.copy(_3foptions) - local opts = _803_ - local _3ffennelrc = _803_["fennelrc"] + local _816_ = copy(_3foptions) + local opts = _816_ + local _3ffennelrc = _816_["fennelrc"] local _ = nil opts.fennelrc = nil _ = nil @@ -595,20 +595,20 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local callbacks = {["view-opts"] = (opts["view-opts"] or {depth = 4}), 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 _805_(_241) + local function _818_(_241) return callbacks.readChunk(_241) end - byte_stream, clear_stream = parser.granulate(_805_) + byte_stream, clear_stream = parser.granulate(_818_) local chars = {} local read, reset = nil, nil - local function _806_(parser_state) + local function _819_(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(_806_) + read, reset = parser.parser(_819_) depth = (depth + 1) if opts.message then callbacks.onValues({opts.message}) @@ -623,14 +623,14 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) opts.init(opts, depth) end if opts.registerCompleter then - local function _812_() - local _811_0 = opts.scope - local function _813_(...) - return completer(env, _811_0, ...) + local function _825_() + local _824_0 = opts.scope + local function _826_(...) + return completer(env, _824_0, ...) end - return _813_ + return _826_ end - opts.registerCompleter(_812_()) + opts.registerCompleter(_825_()) end load_plugin_commands(opts.plugins) if save_locals_3f then @@ -677,28 +677,28 @@ 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, opts) else if not_eof_3f then - local function _817_(...) - local _818_0, _819_0 = ... - if ((_818_0 == true) and (nil ~= _819_0)) then - local src = _819_0 - local function _820_(...) - local _821_0, _822_0 = ... - if ((_821_0 == true) and (nil ~= _822_0)) then - local chunk = _822_0 - local function _823_() + local function _830_(...) + local _831_0, _832_0 = ... + if ((_831_0 == true) and (nil ~= _832_0)) then + local src = _832_0 + local function _833_(...) + local _834_0, _835_0 = ... + if ((_834_0 == true) and (nil ~= _835_0)) then + local chunk = _835_0 + local function _836_() return print_values(save_value(chunk())) end - local function _824_(...) + local function _837_(...) return callbacks.onError("Runtime", ...) end - return xpcall(_823_, _824_) - elseif ((_821_0 == false) and (nil ~= _822_0)) then - local msg = _822_0 + return xpcall(_836_, _837_) + elseif ((_834_0 == false) and (nil ~= _835_0)) then + local msg = _835_0 clear_stream() return callbacks.onError("Compile", msg) end end - local function _827_(...) + local function _840_(...) local src0 = nil if save_locals_3f then src0 = splice_save_locals(env, src, opts.scope) @@ -707,18 +707,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return pcall(specials["load-code"], src0, env) end - return _820_(_827_(...)) - elseif ((_818_0 == false) and (nil ~= _819_0)) then - local msg = _819_0 + return _833_(_840_(...)) + elseif ((_831_0 == false) and (nil ~= _832_0)) then + local msg = _832_0 clear_stream() return callbacks.onError("Compile", msg) end end - local function _829_() + local function _842_() opts["source"] = src_string return opts end - _817_(pcall(compiler.compile, form, _829_())) + _830_(pcall(compiler.compile, form, _842_())) utils.root.options = old_root_options if exit_next_3f then return env.___replLocals___["*1"] @@ -738,30 +738,46 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return value end - local function _835_(overrides, _3fopts) - return repl(utils.copy(_3fopts, utils.copy(overrides))) + local repl_mt = {__index = {repl = repl}} + repl_mt.__call = function(_848_0, _3fopts) + local _849_ = _848_0 + local overrides = _849_ + local view_opts = _849_["view-opts"] + local opts = copy(_3fopts, copy(overrides)) + local _851_ + do + local _850_0 = _3fopts + if (nil ~= _850_0) then + _850_0 = _850_0["view-opts"] + end + _851_ = _850_0 + end + opts["view-opts"] = copy(_851_, copy(view_opts)) + return repl(opts) end - return setmetatable({}, {__call = _835_, __index = {repl = repl}}) + return setmetatable({["view-opts"] = {}}, repl_mt) end package.preload["fennel.specials"] = package.preload["fennel.specials"] or function(...) - local utils = require("fennel.utils") + local _484_ = require("fennel.utils") + local utils = _484_ + local pack = _484_["pack"] + local unpack = _484_["unpack"] local view = require("fennel.view") local parser = require("fennel.parser") local compiler = require("fennel.compiler") - local unpack = (table.unpack or _G.unpack) local SPECIALS = compiler.scopes.global.specials local function str1(x) return tostring(x[1]) end local function wrap_env(env) - local function _475_(_, key) + local function _485_(_, key) if utils["string?"](key) then return env[compiler["global-unmangling"](key)] else return env[key] end end - local function _477_(_, key, value) + local function _487_(_, key, value) if utils["string?"](key) then env[compiler["global-unmangling"](key)] = value return nil @@ -770,28 +786,28 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return nil end end - local function _479_() - local _480_ + local function _489_() + local _490_ do local tbl_14_ = {} for k, v in utils.stablepairs(env) do local k_15_, v_16_ = nil, nil - local _481_ + local _491_ if utils["string?"](k) then - _481_ = compiler["global-unmangling"](k) + _491_ = compiler["global-unmangling"](k) else - _481_ = k + _491_ = k end - k_15_, v_16_ = _481_, v + k_15_, v_16_ = _491_, v if ((k_15_ ~= nil) and (v_16_ ~= nil)) then tbl_14_[k_15_] = v_16_ end end - _480_ = tbl_14_ + _490_ = tbl_14_ end - return next, _480_, nil + return next, _490_, nil end - return setmetatable({}, {__index = _475_, __newindex = _477_, __pairs = _479_}) + return setmetatable({}, {__index = _485_, __newindex = _487_, __pairs = _489_}) end local function fennel_module_name() return (utils.root.options.moduleName or "fennel") @@ -799,9 +815,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function current_global_names(_3fenv) local mt = nil do - local _484_0 = getmetatable(_3fenv) - if ((_G.type(_484_0) == "table") and (nil ~= _484_0.__pairs)) then - local mtpairs = _484_0.__pairs + local _494_0 = getmetatable(_3fenv) + if ((_G.type(_494_0) == "table") and (nil ~= _494_0.__pairs)) then + local mtpairs = _494_0.__pairs local tbl_14_ = {} for k, v in mtpairs(_3fenv) do local k_15_, v_16_ = k, v @@ -810,13 +826,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end mt = tbl_14_ - elseif (_484_0 == nil) then + elseif (_494_0 == nil) then mt = (_3fenv or _G) else mt = nil end end - local function _487_() + local function _497_() local tbl_17_ = {} local i_18_ = #tbl_17_ for k in utils.stablepairs(mt) do @@ -828,19 +844,19 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - return (mt and _487_()) + return (mt and _497_()) end local function load_code(code, _3fenv, _3ffilename) local env = (_3fenv or rawget(_G, "_ENV") or _G) - local _489_0, _490_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") - if ((nil ~= _489_0) and (nil ~= _490_0)) then - local setfenv = _489_0 - local loadstring = _490_0 + local _499_0, _500_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") + if ((nil ~= _499_0) and (nil ~= _500_0)) then + local setfenv = _499_0 + local loadstring = _500_0 local f = assert(loadstring(code, _3ffilename)) setfenv(f, env) return f else - local _ = _489_0 + local _ = _499_0 return assert(load(code, _3ffilename, "t", env)) end end @@ -852,14 +868,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if not tgt then return (name .. " not found") else - local function _493_() - local _492_0 = getmetatable(tgt) - if ((_G.type(_492_0) == "table") and true) then - local __call = _492_0.__call + local function _503_() + local _502_0 = getmetatable(tgt) + if ((_G.type(_502_0) == "table") and true) then + local __call = _502_0.__call return ("function" == type(__call)) end end - if ((type(tgt) == "function") or _493_()) then + if ((type(tgt) == "function") or _503_()) then local elts = {name, unpack(((compiler.metadata):get(tgt, "fnl/arglist") or {"#"}))} return string.format("(%s)\n %s", table.concat(elts, " "), v__3edocstring(tgt)) else @@ -930,7 +946,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("do", {"..."}, "Evaluate multiple forms; return last value.", true) local function iter_args(ast) local ast0, len, i = ast, #ast, 1 - local function _499_() + local function _509_() i = (1 + i) while ((i == len) and utils["call-of?"](ast0[i], "values")) do ast0 = ast0[i] @@ -939,7 +955,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return ast0[i], (nil == ast0[(i + 1)]) end - return _499_ + return _509_ end SPECIALS.values = function(ast, scope, parent) local exprs = {} @@ -983,9 +999,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 _503_ = compiler.compile1(v, scope, chunk, opts) - local _504_ = _503_[1] - local v0 = _504_[1] + local _513_ = compiler.compile1(v, scope, chunk, opts) + local _514_ = _513_[1] + local v0 = _514_[1] return v0 end local function insert_meta(meta, k, v) @@ -993,14 +1009,14 @@ 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 _505_() + local function _515_() if ("string" == type(v)) then return view(v, view_opts) else return compile_value(v) end end - table.insert(meta, _505_()) + table.insert(meta, _515_()) return meta end local function insert_arglist(meta, arg_list) @@ -1032,39 +1048,43 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct insert_meta(meta_fields, k, v) end end - local meta_str = ("require(\"%s\").metadata"):format(fennel_module_name()) - return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", "))) + if (type(utils.root.options.useMetadata) == "string") then + return compiler.emit(parent, ("%s:setall(%s, %s)"):format(utils.root.options.useMetadata, fn_name, table.concat(meta_fields, ", "))) + else + local meta_str = ("require(\"%s\").metadata"):format(fennel_module_name()) + return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", "))) + end end end local function get_fn_name(ast, scope, fn_name, multi) if (fn_name and (fn_name[1] ~= "nil")) then - local _509_ + local _520_ if not multi then - _509_ = compiler["declare-local"](fn_name, scope, ast) + _520_ = compiler["declare-local"](fn_name, scope, ast) else - _509_ = compiler["symbol-to-expression"](fn_name, scope)[1] + _520_ = compiler["symbol-to-expression"](fn_name, scope)[1] end - return _509_, not multi, 3 + return _520_, not multi, 3 else return nil, true, 2 end end local function compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, local_3f, arg_name_list, f_metadata) - utils.hook("pre-fn", ast, f_scope) + utils.hook("pre-fn", ast, f_scope, parent) 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 _512_ + local _523_ if local_3f then - _512_ = "local function %s(%s)" + _523_ = "local function %s(%s)" else - _512_ = "%s = function(%s)" + _523_ = "%s = function(%s)" end - compiler.emit(parent, string.format(_512_, fn_name, table.concat(arg_name_list, ", ")), ast) + compiler.emit(parent, string.format(_523_, 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) - utils.hook("fn", ast, f_scope) + utils.hook("fn", ast, f_scope, parent) return utils.expr(fn_name, "sym") end local function compile_anonymous_fn(ast, f_scope, f_chunk, parent, index, arg_name_list, f_metadata, scope) @@ -1082,7 +1102,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function get_function_metadata(ast, arg_list, index) - local function _515_(_241, _242) + local function _526_(_241, _242) local tbl_14_ = _241 for k, v in pairs(_242) do local k_15_, v_16_ = k, v @@ -1092,18 +1112,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_14_ end - local function _517_(_241, _242) + local function _528_(_241, _242) _241["fnl/docstring"] = _242 return _241 end - return maybe_metadata(ast, utils["kv-table?"], _515_, maybe_metadata(ast, utils["string?"], _517_, {["fnl/arglist"] = arg_list}, index)) + return maybe_metadata(ast, utils["kv-table?"], _526_, maybe_metadata(ast, utils["string?"], _528_, {["fnl/arglist"] = arg_list}, index)) end SPECIALS.fn = function(ast, scope, parent, opts) local f_scope = nil do - local _518_0 = compiler["make-scope"](scope) - _518_0["vararg"] = false - f_scope = _518_0 + local _529_0 = compiler["make-scope"](scope) + _529_0["vararg"] = false + f_scope = _529_0 end local f_chunk = {} local fn_sym = utils["sym?"](ast[2]) @@ -1166,28 +1186,28 @@ 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 _524_ + local _535_ do - local _523_0 = utils["sym?"](ast[2]) - if (nil ~= _523_0) then - _524_ = tostring(_523_0) + local _534_0 = utils["sym?"](ast[2]) + if (nil ~= _534_0) then + _535_ = tostring(_534_0) else - _524_ = _523_0 + _535_ = _534_0 end end - if ("nil" ~= _524_) then + if ("nil" ~= _535_) then table.insert(parent, {ast = ast, leaf = tostring(ast[2])}) end - local _528_ + local _539_ do - local _527_0 = utils["sym?"](ast[3]) - if (nil ~= _527_0) then - _528_ = tostring(_527_0) + local _538_0 = utils["sym?"](ast[3]) + if (nil ~= _538_0) then + _539_ = tostring(_538_0) else - _528_ = _527_0 + _539_ = _538_0 end end - if ("nil" ~= _528_) then + if ("nil" ~= _539_) then return tostring(ast[3]) end end @@ -1195,8 +1215,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((1 < #ast), "expected table argument", ast) local len = #ast local lhs_node = compiler.macroexpand(ast[2], scope) - local _531_ = compiler.compile1(lhs_node, scope, parent, {nval = 1}) - local lhs = _531_[1] + local _542_ = compiler.compile1(lhs_node, scope, parent, {nval = 1}) + local lhs = _542_[1] if (len == 2) then return tostring(lhs) else @@ -1206,8 +1226,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 _532_ = compiler.compile1(index, scope, parent, {nval = 1}) - local index0 = _532_[1] + local _543_ = compiler.compile1(index, scope, parent, {nval = 1}) + local index0 = _543_[1] table.insert(indices, ("[" .. tostring(index0) .. "]")) end end @@ -1254,7 +1274,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 _536_ + local _547_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1270,15 +1290,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _536_ = tbl_17_ + _547_ = tbl_17_ end - return _536_[1] + return _547_[1] end - SPECIALS.let = function(_539_0, scope, parent, opts) - local _540_ = _539_0 - local _ = _540_[1] - local bindings = _540_[2] - local ast = _540_ + SPECIALS.let = function(_550_0, scope, parent, opts) + local _551_ = _550_0 + local _ = _551_[1] + local bindings = _551_[2] + local ast = _551_ compiler.assert((utils["table?"](bindings) and not kv_3f(bindings)), "expected binding sequence", (bindings or ast[1])) compiler.assert(((#bindings % 2) == 0), "expected even number of name/value bindings", bindings) compiler.assert((3 <= #ast), "expected body expression", ast[1]) @@ -1385,8 +1405,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end for i = 2, (#ast - 1), 2 do local condchunk = {} - local _549_ = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1}) - local cond = _549_[1] + local _560_ = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1}) + local cond = _560_[1] local branch = compile_body((i + 1)) branch.cond = cond branch.condchunk = condchunk @@ -1456,10 +1476,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function remove_until_condition(bindings, ast) local _until = nil for i = (#bindings - 1), 3, -1 do - local _555_0 = clause_3f(bindings[i]) - if ((_555_0 == false) or (_555_0 == nil)) then - elseif (nil ~= _555_0) then - local clause = _555_0 + local _566_0 = clause_3f(bindings[i]) + if ((_566_0 == false) or (_566_0 == nil)) then + elseif (nil ~= _566_0) then + local clause = _566_0 compiler.assert(((clause == "until") and not _until), ("unexpected iterator clause: " .. clause), ast) table.remove(bindings, i) _until = table.remove(bindings, i) @@ -1469,8 +1489,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function compile_until(_3fcondition, scope, chunk) if _3fcondition then - local _557_ = compiler.compile1(_3fcondition, scope, chunk, {nval = 1}) - local condition_lua = _557_[1] + local _568_ = compiler.compile1(_3fcondition, scope, chunk, {nval = 1}) + local condition_lua = _568_[1] return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(_3fcondition, "expression")) end end @@ -1603,10 +1623,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function native_method_call(ast, _scope, _parent, target, args) - local _566_ = ast - local _ = _566_[1] - local _0 = _566_[2] - local method_string = _566_[3] + local _577_ = ast + local _ = _577_[1] + local _0 = _577_[2] + local method_string = _577_[3] local call_string = nil if ((target.type == "literal") or (target.type == "varg") or ((target.type == "expression") and not (target[1]):match("[%)%]]$") and not (target[1]):match("%.[%a_][%w_]*$"))) then call_string = "(%s):%s(%s)" @@ -1629,18 +1649,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 _568_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local target = _568_[1] + local _579_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local target = _579_[1] local args = {} for i = 4, #ast do local subexprs = nil - local _569_ + local _580_ if (i ~= #ast) then - _569_ = 1 + _580_ = 1 else - _569_ = nil + _580_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _569_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _580_}) local tbl_17_ = args local i_18_ = #tbl_17_ for _, subexpr in ipairs(subexprs) do @@ -1651,12 +1671,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end end - local _572_0 = method_special_type(ast) - if (_572_0 == "native") then + local _583_0 = method_special_type(ast) + if (_583_0 == "native") then return native_method_call(ast, scope, parent, target, args) - elseif (_572_0 == "nonnative") then + elseif (_583_0 == "nonnative") then return nonnative_method_call(ast, scope, parent, target, args) - elseif (_572_0 == "binding") then + elseif (_583_0 == "binding") then return binding_method_call(ast, scope, parent, target, args) end end @@ -1664,7 +1684,7 @@ 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 _574_ + local _585_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1680,9 +1700,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _574_ = tbl_17_ + _585_ = tbl_17_ end - c = table.concat(_574_, " "):gsub("%]%]", "]\\]") + c = table.concat(_585_, " "):gsub("%]%]", "]\\]") return compiler.emit(parent, ("--[[ " .. c .. " ]]"), ast) end doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true) @@ -1703,10 +1723,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 _579_0 = compiler["make-scope"](scope) - _579_0["vararg"] = false - _579_0["hashfn"] = true - f_scope = _579_0 + local _590_0 = compiler["make-scope"](scope) + _590_0["vararg"] = false + _590_0["hashfn"] = true + f_scope = _590_0 end local f_chunk = {} local name = compiler.gensym(scope) @@ -1768,33 +1788,33 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return ok elseif utils["list?"](x) then if utils["sym?"](x[1]) then - local _585_0 = str1(x) - if ((_585_0 == "fn") or (_585_0 == "hashfn") or (_585_0 == "let") or (_585_0 == "local") or (_585_0 == "var") or (_585_0 == "set") or (_585_0 == "tset") or (_585_0 == "if") or (_585_0 == "each") or (_585_0 == "for") or (_585_0 == "while") or (_585_0 == "do") or (_585_0 == "lua") or (_585_0 == "global")) then + local _596_0 = str1(x) + if ((_596_0 == "fn") or (_596_0 == "hashfn") or (_596_0 == "let") or (_596_0 == "local") or (_596_0 == "var") or (_596_0 == "set") or (_596_0 == "tset") or (_596_0 == "if") or (_596_0 == "each") or (_596_0 == "for") or (_596_0 == "while") or (_596_0 == "do") or (_596_0 == "lua") or (_596_0 == "global")) then return false - elseif (((_585_0 == "<") or (_585_0 == ">") or (_585_0 == "<=") or (_585_0 == ">=") or (_585_0 == "=") or (_585_0 == "not=") or (_585_0 == "~=")) and (comparator_special_type(x) == "binding")) then + elseif (((_596_0 == "<") or (_596_0 == ">") or (_596_0 == "<=") or (_596_0 == ">=") or (_596_0 == "=") or (_596_0 == "not=") or (_596_0 == "~=")) and (comparator_special_type(x) == "binding")) then return false else - local function _586_() + local function _597_() return (1 ~= x[2]) end - if ((_585_0 == "pick-values") and _586_()) then + if ((_596_0 == "pick-values") and _597_()) then return false else - local function _587_() - local call = _585_0 + local function _598_() + local call = _596_0 return scope.macros[call] end - if ((nil ~= _585_0) and _587_()) then - local call = _585_0 + if ((nil ~= _596_0) and _598_()) then + local call = _596_0 return false else - local function _588_() + local function _599_() return (method_special_type(x) == "binding") end - if ((_585_0 == ":") and _588_()) then + if ((_596_0 == ":") and _599_()) then return false else - local _ = _585_0 + local _ = _596_0 local ok = true for i = 2, #x do if not ok then break end @@ -1816,21 +1836,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function operator_special_result(ast, zero_arity, unary_prefix, padded_op, operands) - local _592_0 = #operands - if (_592_0 == 0) then + local _603_0 = #operands + if (_603_0 == 0) then if zero_arity then return utils.expr(zero_arity, "literal") else return compiler.assert(false, "Expected more than 0 arguments", ast) end - elseif (_592_0 == 1) then + elseif (_603_0 == 1) then if unary_prefix then return ("(" .. unary_prefix .. padded_op .. operands[1] .. ")") else return operands[1] end else - local _ = _592_0 + local _ = _603_0 return ("(" .. table.concat(operands, padded_op) .. ")") end end @@ -1838,14 +1858,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if (accumulator ~= expr_string) then compiler.emit(parent, string.format(setter, accumulator, expr_string), ast) end - local function _597_() + local function _608_() if (name == "and") then return accumulator else return ("not " .. accumulator) end end - compiler.emit(parent, ("if %s then"):format(_597_()), subast) + compiler.emit(parent, ("if %s then"):format(_608_()), subast) do local chunk = {} compiler.compile1(subast, scope, chunk, {nval = 1, target = accumulator}) @@ -1881,15 +1901,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return operator_special_result(ast, zero_arity, unary_prefix, padded_op, operands) end local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name) - local _603_ + local _614_ do - local _602_0 = (_3flua_name or name) - local function _604_(...) - return operator_special(_602_0, zero_arity, unary_prefix, ...) + local _613_0 = (_3flua_name or name) + local function _615_(...) + return operator_special(_613_0, zero_arity, unary_prefix, ...) end - _603_ = _604_ + _614_ = _615_ end - SPECIALS[name] = _603_ + SPECIALS[name] = _614_ return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.") end define_arithmetic_special("+", "0", "0") @@ -1918,13 +1938,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 _605_ + local _616_ if (i ~= len) then - _605_ = 1 + _616_ = 1 else - _605_ = nil + _616_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _605_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _616_}) local tbl_17_ = operands local i_18_ = #tbl_17_ for _, s in ipairs(subexprs) do @@ -1951,10 +1971,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 _612_(...) + local function _623_(...) return bitop_special(native, name, zero_arity, unary_prefix, ...) end - SPECIALS[name] = _612_ + SPECIALS[name] = _623_ return nil end define_bitop_special("lshift", nil, "1", "<<") @@ -1969,8 +1989,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 _613_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local value = _613_[1] + local _624_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local value = _624_[1] if utils.root.options.useBitLib then return ("bit.bnot(" .. tostring(value) .. ")") else @@ -1979,15 +1999,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, _615_0, scope, parent) - local _616_ = _615_0 - local _ = _616_[1] - local lhs_ast = _616_[2] - local rhs_ast = _616_[3] - local _617_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) - local lhs = _617_[1] - local _618_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) - local rhs = _618_[1] + local function native_comparator(op, _626_0, scope, parent) + local _627_ = _626_0 + local _ = _627_[1] + local lhs_ast = _627_[2] + local rhs_ast = _627_[3] + local _628_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) + local lhs = _628_[1] + local _629_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) + local rhs = _629_[1] return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs)) end local function idempotent_comparator(op, chain_op, ast, scope, parent) @@ -2037,7 +2057,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end compiler.emit(parent, string.format("local %s = %s", table.concat(binding_left, ", "), table.concat(binding_right, ", "), ast)) - local _622_ + local _633_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -2048,24 +2068,24 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _622_ = tbl_17_ + _633_ = tbl_17_ end - return ("(" .. table.concat(_622_, chain) .. ")") + return ("(" .. table.concat(_633_, chain) .. ")") end local function define_comparator_special(name, _3flua_op, _3fchain_op) do local op = (_3flua_op or name) local function opfn(ast, scope, parent) compiler.assert((2 < #ast), "expected at least two arguments", ast) - local _624_0 = comparator_special_type(ast) - if (_624_0 == "native") then + local _635_0 = comparator_special_type(ast) + if (_635_0 == "native") then return native_comparator(op, ast, scope, parent) - elseif (_624_0 == "idempotent") then + elseif (_635_0 == "idempotent") then return idempotent_comparator(op, _3fchain_op, ast, scope, parent) - elseif (_624_0 == "binding") then + elseif (_635_0 == "binding") then return binding_comparator(op, _3fchain_op, ast, scope, parent) else - local _ = _624_0 + local _ = _635_0 return error("internal compiler error. please report this to the fennel devs.") end end @@ -2094,16 +2114,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("length", {"x"}, "Returns the length of a table or string.") SPECIALS["~="] = SPECIALS["not="] SPECIALS["#"] = SPECIALS.length + local function compile_time_3f(scope) + return ((scope == compiler.scopes.compiler) or (scope.parent and compile_time_3f(scope.parent))) + end SPECIALS.quote = function(ast, scope, parent) compiler.assert((#ast == 2), "expected one argument", ast) - local runtime, this_scope = true, scope - while this_scope do - this_scope = this_scope.parent - if (this_scope == compiler.scopes.compiler) then - runtime = false - end - end - return compiler["do-quote"](ast[2], scope, parent, runtime) + return compiler["do-quote"](ast[2], scope, parent, not compile_time_3f(scope)) end doc_special("quote", {"x"}, "Quasiquote the following form. Only works in macro/compiler scope.") local macro_loaded = {} @@ -2114,21 +2130,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local safe_require = nil local function safe_compiler_env() - local _628_ + local _638_ do - local _627_0 = rawget(_G, "utf8") - if (nil ~= _627_0) then - _628_ = utils.copy(_627_0) + local _637_0 = rawget(_G, "utf8") + if (nil ~= _637_0) then + _638_ = utils.copy(_637_0) else - _628_ = _627_0 + _638_ = _637_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 = _628_, 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 = _638_, xpcall = xpcall} end local function combined_mt_pairs(env) local combined = {} - local _630_ = getmetatable(env) - local __index = _630_["__index"] + local _640_ = getmetatable(env) + local __index = _640_["__index"] if ("table" == type(__index)) then for k, v in pairs(__index) do combined[k] = v @@ -2142,40 +2158,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 _632_0 = (_3fopts or utils.root.options) - if ((_G.type(_632_0) == "table") and (_632_0["compiler-env"] == "strict")) then + local _642_0 = (_3fopts or utils.root.options) + if ((_G.type(_642_0) == "table") and (_642_0["compiler-env"] == "strict")) then provided = safe_compiler_env() - elseif ((_G.type(_632_0) == "table") and (nil ~= _632_0.compilerEnv)) then - local compilerEnv = _632_0.compilerEnv + elseif ((_G.type(_642_0) == "table") and (nil ~= _642_0.compilerEnv)) then + local compilerEnv = _642_0.compilerEnv provided = compilerEnv - elseif ((_G.type(_632_0) == "table") and (nil ~= _632_0["compiler-env"])) then - local compiler_env = _632_0["compiler-env"] + elseif ((_G.type(_642_0) == "table") and (nil ~= _642_0["compiler-env"])) then + local compiler_env = _642_0["compiler-env"] provided = compiler_env else - local _ = _632_0 + local _ = _642_0 provided = safe_compiler_env() end end local env = nil - local function _634_() + local function _644_() return compiler.scopes.macro end - local function _635_(symbol) + local function _645_(symbol) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.scopes.macro.manglings[tostring(symbol)] end - local function _636_(base) + local function _646_(base) return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base)) end - local function _637_(form) + local function _647_(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?"], ["fennel-module-name"] = fennel_module_name, ["get-scope"] = _634_, ["in-scope?"] = _635_, ["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 = _636_, list = utils.list, macroexpand = _637_, 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?"], ["fennel-module-name"] = fennel_module_name, ["get-scope"] = _644_, ["in-scope?"] = _645_, ["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 = _646_, list = utils.list, macroexpand = _647_, pack = pack, 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 _638_(...) + local function _648_(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for c in string.gmatch((package.config or ""), "([^\n]+)") do @@ -2187,10 +2203,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - local _640_ = _638_(...) - local dirsep = _640_[1] - local pathsep = _640_[2] - local pathmark = _640_[3] + local _650_ = _648_(...) + local dirsep = _650_[1] + local pathsep = _650_[2] + local pathmark = _650_[3] local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or "?"), pathsep = (pathsep or ";")} local function escapepat(str) return string.gsub(str, "[^%w]", "%%%1") @@ -2202,37 +2218,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local fullpath = ((_3fpathstring or utils["fennel-module"].path) .. pkg_config.pathsep) 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 _641_0 = (io.open(filename) or io.open(filename2)) - if (nil ~= _641_0) then - local file = _641_0 + local _651_0 = io.open(filename) + if (nil ~= _651_0) then + local file = _651_0 file:close() return filename else - local _ = _641_0 + local _ = _651_0 return nil, ("no file '" .. filename .. "'") end end local function find_in_path(start, _3ftried_paths) - local _643_0 = fullpath:match(pattern, start) - if (nil ~= _643_0) then - local path = _643_0 - local _644_0, _645_0 = try_path(path) - if (nil ~= _644_0) then - local filename = _644_0 + local _653_0 = fullpath:match(pattern, start) + if (nil ~= _653_0) then + local path = _653_0 + local _654_0, _655_0 = try_path(path) + if (nil ~= _654_0) then + local filename = _654_0 return filename - elseif ((_644_0 == nil) and (nil ~= _645_0)) then - local error = _645_0 - local function _647_() - local _646_0 = (_3ftried_paths or {}) - table.insert(_646_0, error) - return _646_0 + elseif ((_654_0 == nil) and (nil ~= _655_0)) then + local error = _655_0 + local function _657_() + local _656_0 = (_3ftried_paths or {}) + table.insert(_656_0, error) + return _656_0 end - return find_in_path((start + #path + 1), _647_()) + return find_in_path((start + #path + 1), _657_()) end else - local _ = _643_0 - local function _649_() + local _ = _653_0 + local function _659_() local tried_paths = table.concat((_3ftried_paths or {}), "\n\9") if (_VERSION < "Lua 5.4") then return ("\n\9" .. tried_paths) @@ -2240,31 +2255,31 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return tried_paths end end - return nil, _649_() + return nil, _659_() end end return find_in_path(1) end local function make_searcher(_3foptions) - local function _652_(module_name) + local function _662_(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 _653_0, _654_0 = search_module(module_name) - if (nil ~= _653_0) then - local filename = _653_0 - local function _655_(...) + local _663_0, _664_0 = search_module(module_name) + if (nil ~= _663_0) then + local filename = _663_0 + local function _665_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - return _655_, filename - elseif ((_653_0 == nil) and (nil ~= _654_0)) then - local error = _654_0 + return _665_, filename + elseif ((_663_0 == nil) and (nil ~= _664_0)) then + local error = _664_0 return error end end - return _652_ + return _662_ end local function dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) local searchers = (package.loaders or package.searchers or {}) @@ -2276,35 +2291,35 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function fennel_macro_searcher(module_name) local opts = nil do - local _657_0 = utils.copy(utils.root.options) - _657_0["module-name"] = module_name - _657_0["env"] = "_COMPILER" - _657_0["requireAsInclude"] = false - _657_0["allowedGlobals"] = nil - opts = _657_0 + local _667_0 = utils.copy(utils.root.options) + _667_0["module-name"] = module_name + _667_0["env"] = "_COMPILER" + _667_0["requireAsInclude"] = false + _667_0["allowedGlobals"] = nil + opts = _667_0 end - local _658_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) - if (nil ~= _658_0) then - local filename = _658_0 - local _659_ + local _668_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) + if (nil ~= _668_0) then + local filename = _668_0 + local _669_ if (opts["compiler-env"] == _G) then - local function _660_(...) + local function _670_(...) return dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) end - _659_ = _660_ + _669_ = _670_ else - local function _661_(...) + local function _671_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - _659_ = _661_ + _669_ = _671_ end - return _659_, filename + return _669_, filename end end local function lua_macro_searcher(module_name) - local _664_0 = search_module(module_name, package.path) - if (nil ~= _664_0) then - local filename = _664_0 + local _674_0 = search_module(module_name, package.path) + if (nil ~= _674_0) then + local filename = _674_0 local code = nil do local f = io.open(filename) @@ -2316,10 +2331,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _666_() + local function _676_() return assert(f:read("*a")) end - code = close_handlers_10_(_G.xpcall(_666_, (package.loaded.fennel or debug).traceback)) + code = close_handlers_10_(_G.xpcall(_676_, (package.loaded.fennel or debug).traceback)) end local chunk = load_code(code, make_compiler_env(), filename) return chunk, filename @@ -2327,38 +2342,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 _668_0 = macro_searchers[n] - if (nil ~= _668_0) then - local f = _668_0 - local _669_0, _670_0 = f(modname) - if ((nil ~= _669_0) and true) then - local loader = _669_0 - local _3ffilename = _670_0 + local _678_0 = macro_searchers[n] + if (nil ~= _678_0) then + local f = _678_0 + local _679_0, _680_0 = f(modname) + if ((nil ~= _679_0) and true) then + local loader = _679_0 + local _3ffilename = _680_0 return loader, _3ffilename else - local _ = _669_0 + local _ = _679_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 - local function _673_(_, ...) + local function _683_(_, ...) return (compiler.metadata):setall(...) end - return {metadata = {setall = _673_}, view = view} + return {metadata = {setall = _683_}, view = view} end end - local function _675_(modname) - local function _676_() + local function _685_(modname) + local function _686_() 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 _676_()) + return (macro_loaded[modname] or sandbox_fennel_module(modname) or _686_()) end - safe_require = _675_ + safe_require = _685_ 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 @@ -2368,10 +2383,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return nil end - local function resolve_module_name(_677_0, _scope, _parent, opts) - local _678_ = _677_0 - local second = _678_[2] - local filename = _678_["filename"] + local function resolve_module_name(_687_0, _scope, _parent, opts) + local _688_ = _687_0 + local second = _688_[2] + local filename = _688_["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) @@ -2428,10 +2443,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _684_() + local function _694_() return assert(f:read("*all")):gsub("[\13\n]*$", "") end - src = close_handlers_10_(_G.xpcall(_684_, (package.loaded.fennel or debug).traceback)) + src = close_handlers_10_(_G.xpcall(_694_, (package.loaded.fennel or debug).traceback)) end local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement") local target = ("package.preload[%q]"):format(mod) @@ -2461,12 +2476,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local modexpr = nil do - local _687_0, _688_0 = pcall(resolve_module_name, ast, scope, parent, opts) - if ((_687_0 == true) and (nil ~= _688_0)) then - local modname = _688_0 + local _697_0, _698_0 = pcall(resolve_module_name, ast, scope, parent, opts) + if ((_697_0 == true) and (nil ~= _698_0)) then + local modname = _698_0 modexpr = utils.expr(string.format("%q", modname), "literal") else - local _ = _687_0 + local _ = _697_0 modexpr = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] end end @@ -2483,13 +2498,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct utils.root.options["module-name"] = mod _ = nil local res = nil - local function _692_() - local _691_0 = search_module(mod) - if (nil ~= _691_0) then - local fennel_path = _691_0 + local function _702_() + local _701_0 = search_module(mod) + if (nil ~= _701_0) then + local fennel_path = _701_0 return include_path(ast, opts, fennel_path, mod, true) else - local _0 = _691_0 + local _0 = _701_0 local lua_path = search_module(mod, package.path) if lua_path then return include_path(ast, opts, lua_path, mod, false) @@ -2500,7 +2515,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 _692_()) + 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 _702_()) utils.root.options["module-name"] = oldmod return res end @@ -2534,9 +2549,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local vals = utils.list(utils.sym("values"), unpack(ast, 3)) compiler.assert((("number" == type(n)) and (0 <= n) and (n == math.floor(n))), ("Expected n to be an integer >= 0, got " .. tostring(n))) if (1 == n) then - local _696_ = compiler.compile1(vals, scope, parent, {nval = 1}) - local _697_ = _696_[1] - local expr = _697_[1] + local _706_ = compiler.compile1(vals, scope, parent, {nval = 1}) + local _707_ = _706_[1] + local expr = _707_[1] return {("(" .. expr .. ")")} elseif (0 == n) then for i = 3, #ast do @@ -2577,21 +2592,22 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return {["current-global-names"] = current_global_names, ["get-function-metadata"] = get_function_metadata, ["load-code"] = load_code, ["macro-loaded"] = macro_loaded, ["macro-searchers"] = macro_searchers, ["make-compiler-env"] = make_compiler_env, ["make-searcher"] = make_searcher, ["search-module"] = search_module, ["wrap-env"] = wrap_env, doc = doc_2a} end package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or function(...) - local utils = require("fennel.utils") + local _281_ = require("fennel.utils") + local utils = _281_ + local unpack = _281_["unpack"] local parser = require("fennel.parser") local friend = require("fennel.friend") local view = require("fennel.view") - local unpack = (table.unpack or _G.unpack) local scopes = {compiler = nil, global = nil, macro = nil} local function make_scope(_3fparent) local parent = (_3fparent or scopes.global) - local _275_ + local _282_ if parent then - _275_ = ((parent.depth or 0) + 1) + _282_ = ((parent.depth or 0) + 1) else - _275_ = 0 + _282_ = 0 end - return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _275_, 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 = _282_, 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 @@ -2609,10 +2625,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 _278_ = (utils.root.options or {}) - local error_pinpoint = _278_["error-pinpoint"] - local source = _278_["source"] - local unfriendly = _278_["unfriendly"] + local _285_ = (utils.root.options or {}) + local error_pinpoint = _285_["error-pinpoint"] + local source = _285_["source"] + local unfriendly = _285_["unfriendly"] local ast0 = nil if next(utils["ast-source"](ast)) then ast0 = ast @@ -2634,45 +2650,58 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct scopes.global.vararg = true scopes.compiler = make_scope(scopes.global) scopes.macro = scopes.global + local serialize_subst_digits = {["\\10"] = "\\n", ["\\11"] = "\\v", ["\\12"] = "\\f", ["\\13"] = "\\r", ["\\7"] = "\\a", ["\\8"] = "\\b", ["\\9"] = "\\t"} local function serialize_string(str) - local function _283_(_241) + local function _290_(_241) return ("\\" .. _241:byte()) end - return string.gsub(string.gsub(string.gsub(string.format("%q", str), "\\\n", "\\n"), "\\9", "\\t"), "[\128-\255]", _283_) + return string.gsub(string.gsub(string.gsub(string.format("%q", str), "\\\n", "\\n"), "\\..?", serialize_subst_digits), "[\128-\255]", _290_) end local function global_mangling(str) if utils["valid-lua-identifier?"](str) then return str else - local function _284_(_241) - return string.format("_%02x", _241:byte()) + local _292_ + do + local _291_0 = utils.root.options + if (nil ~= _291_0) then + _291_0 = _291_0["global-mangle"] + end + _292_ = _291_0 + end + if (_292_ == false) then + return ("_G[%q]"):format(str) + else + local function _294_(_241) + return string.format("_%02x", _241:byte()) + end + return ("__fnl_global__" .. str:gsub("[^%w]", _294_)) end - return ("__fnl_global__" .. str:gsub("[^%w]", _284_)) end end local function global_unmangling(identifier) - local _286_0 = string.match(identifier, "^__fnl_global__(.*)$") - if (nil ~= _286_0) then - local rest = _286_0 - local _287_0 = nil - local function _288_(_241) + local _296_0 = string.match(identifier, "^__fnl_global__(.*)$") + if (nil ~= _296_0) then + local rest = _296_0 + local _297_0 = nil + local function _298_(_241) return string.char(tonumber(_241:sub(2), 16)) end - _287_0 = string.gsub(rest, "_[%da-f][%da-f]", _288_) - return _287_0 + _297_0 = rest:gsub("_[%da-f][%da-f]", _298_) + return _297_0 else - local _ = _286_0 + local _ = _296_0 return identifier end end local function global_allowed_3f(name) local allowed = nil do - local _290_0 = utils.root.options - if (nil ~= _290_0) then - _290_0 = _290_0.allowedGlobals + local _300_0 = utils.root.options + if (nil ~= _300_0) then + _300_0 = _300_0.allowedGlobals end - allowed = _290_0 + allowed = _300_0 end return (not allowed or utils["member?"](name, allowed)) end @@ -2736,29 +2765,29 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(parts, ".") end local function autogensym(base, scope) - local _296_0 = utils["multi-sym?"](base) - if (nil ~= _296_0) then - local parts = _296_0 + local _306_0 = utils["multi-sym?"](base) + if (nil ~= _306_0) then + local parts = _306_0 return combine_auto_gensym(parts, autogensym(parts[1], scope)) else - local _ = _296_0 - local function _297_() + local _ = _306_0 + local function _307_() local mangling = gensym(scope, base:sub(1, -2), "auto") scope.autogensyms[base] = mangling return mangling end - return (scope.autogensyms[base] or _297_()) + return (scope.autogensyms[base] or _307_()) end end local function check_binding_valid(symbol, scope, ast, _3fopts) local name = tostring(symbol) local macro_3f = nil do - local _299_0 = _3fopts - if (nil ~= _299_0) then - _299_0 = _299_0["macro?"] + local _309_0 = _3fopts + if (nil ~= _309_0) then + _309_0 = _309_0["macro?"] end - macro_3f = _299_0 + macro_3f = _309_0 end assert_compile(("&" ~= name:match("[&.:]")), "invalid character: &", symbol) assert_compile(not name:find("^%."), "invalid character: .", symbol) @@ -2776,10 +2805,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct raw = str end local mangling = nil - local function _302_(_241) + local function _312_(_241) return string.format("_%02x", _241:byte()) end - mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _302_) + mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _312_) local unique = unique_mangling(mangling, mangling, scope, 0) scope.unmanglings[unique] = (scope["gensym-base"][str] or str) do @@ -2816,14 +2845,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not scope.macros[parts[1]], "tried to reference a macro without calling it", symbol) assert_compile((not scope.specials[parts[1]] or ("require" == parts[1])), "tried to reference a special form without calling it", symbol) assert_compile((not _3freference_3f or local_3f or ("_ENV" == parts[1]) or global_allowed_3f(parts[1])), ("unknown identifier: " .. tostring(parts[1])), symbol) - local function _307_() - local _306_0 = utils.root.options - if (nil ~= _306_0) then - _306_0 = _306_0.allowedGlobals + local function _317_() + local _316_0 = utils.root.options + if (nil ~= _316_0) then + _316_0 = _316_0.allowedGlobals end - return _306_0 + return _316_0 end - if (_307_() and not local_3f and scope.parent) then + if (_317_() and not local_3f and scope.parent) then scope.parent.refedglobals[parts[1]] = true end return utils.expr(combine_parts(parts, scope), etype) @@ -2890,10 +2919,10 @@ 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 _317_ = utils["ast-source"](chunk.ast) - local endline = _317_["endline"] - local filename = _317_["filename"] - local line = _317_["line"] + local _327_ = utils["ast-source"](chunk.ast) + local endline = _327_["endline"] + local filename = _327_["filename"] + local line = _327_["line"] if ("end" == chunk.leaf) then table.insert(file_sourcemap, {filename, (endline or line)}) else @@ -2903,21 +2932,21 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else local tab0 = nil do - local _319_0 = tab - if (_319_0 == true) then + local _329_0 = tab + if (_329_0 == true) then tab0 = " " - elseif (_319_0 == false) then + elseif (_329_0 == false) then tab0 = "" - elseif (nil ~= _319_0) then - local tab1 = _319_0 + elseif (nil ~= _329_0) then + local tab1 = _329_0 tab0 = tab1 - elseif (_319_0 == nil) then + elseif (_329_0 == nil) then tab0 = "" else tab0 = nil end end - local _321_ + local _331_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -2938,9 +2967,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _321_ = tbl_17_ + _331_ = tbl_17_ end - return table.concat(_321_, "\n") + return table.concat(_331_, "\n") end end local sourcemap = {} @@ -2971,7 +3000,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function make_metadata() - local function _329_(self, tgt, _3fkey) + local function _339_(self, tgt, _3fkey) if self[tgt] then if (nil ~= _3fkey) then return self[tgt][_3fkey] @@ -2980,12 +3009,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end end - local function _332_(self, tgt, key, value) + local function _342_(self, tgt, key, value) self[tgt] = (self[tgt] or {}) self[tgt][key] = value return tgt end - local function _333_(self, tgt, ...) + local function _343_(self, tgt, ...) local kv_len = select("#", ...) local kvs = {...} if ((kv_len % 2) ~= 0) then @@ -2997,10 +3026,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return tgt end - return setmetatable({}, {__index = {get = _329_, set = _332_, setall = _333_}, __mode = "k"}) + return setmetatable({}, {__index = {get = _339_, set = _342_, setall = _343_}, __mode = "k"}) end local function exprs1(exprs) - local _335_ + local _345_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3011,9 +3040,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _335_ = tbl_17_ + _345_ = tbl_17_ end - return table.concat(_335_, ", ") + return table.concat(_345_, ", ") end local function keep_side_effects(exprs, chunk, _3fstart, ast) for j = (_3fstart or 1), #exprs do @@ -3055,14 +3084,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end if opts.target then local result = exprs1(exprs) - local function _343_() + local function _353_() if (result == "") then return "nil" else return result end end - emit(parent, string.format("%s = %s", opts.target, _343_()), ast) + emit(parent, string.format("%s = %s", opts.target, _353_()), ast) end if (opts.tail or opts.target) then return {returned = true} @@ -3074,16 +3103,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function find_macro(ast, scope) local macro_2a = nil do - local _346_0 = utils["sym?"](ast[1]) - if (_346_0 ~= nil) then - local _347_0 = tostring(_346_0) - if (_347_0 ~= nil) then - macro_2a = scope.macros[_347_0] + local _356_0 = utils["sym?"](ast[1]) + if (_356_0 ~= nil) then + local _357_0 = tostring(_356_0) + if (_357_0 ~= nil) then + macro_2a = scope.macros[_357_0] else - macro_2a = _347_0 + macro_2a = _357_0 end else - macro_2a = _346_0 + macro_2a = _356_0 end end local multi_sym_parts = utils["multi-sym?"](ast[1]) @@ -3095,12 +3124,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macro_2a end end - local function propagate_trace_info(_351_0, _index, node) - local _352_ = _351_0 - local byteend = _352_["byteend"] - local bytestart = _352_["bytestart"] - local filename = _352_["filename"] - local line = _352_["line"] + local function propagate_trace_info(_361_0, _index, node) + local _362_ = _361_0 + local byteend = _362_["byteend"] + local bytestart = _362_["bytestart"] + local filename = _362_["filename"] + local line = _362_["line"] do local src = utils["ast-source"](node) if (("table" == type(node)) and (filename ~= src.filename)) then @@ -3113,8 +3142,7 @@ 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 _354_0 = parent[i] - if (_354_0 == nil) then + if (nil == parent[i]) then parent[i] = utils.sym("nil") end end @@ -3130,36 +3158,36 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return found_3f end local function macroexpand_2a(ast, scope, _3fonce) - local _357_0 = nil + local _366_0 = nil if utils["list?"](ast) then - _357_0 = find_macro(ast, scope) + _366_0 = find_macro(ast, scope) else - _357_0 = nil + _366_0 = nil end - if (_357_0 == false) then + if (_366_0 == false) then return ast - elseif (nil ~= _357_0) then - local macro_2a = _357_0 + elseif (nil ~= _366_0) then + local macro_2a = _366_0 local old_scope = scopes.macro local _ = nil scopes.macro = scope _ = nil local ok, transformed = nil, nil - local function _359_() + local function _368_() return macro_2a(unpack(ast, 2)) end - local function _360_() + local function _369_() if built_in_3f(macro_2a) then return tostring else return debug.traceback end end - ok, transformed = xpcall(_359_, _360_()) - local function _361_(...) + ok, transformed = xpcall(_368_, _369_()) + local function _370_(...) return propagate_trace_info(ast, quote_literal_nils(...)) end - utils["walk-tree"](transformed, _361_) + utils["walk-tree"](transformed, _370_) scopes.macro = old_scope assert_compile(ok, transformed, ast) utils.hook("macroexpand", ast, transformed, scope) @@ -3169,7 +3197,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macroexpand_2a(transformed, scope) end else - local _ = _357_0 + local _ = _366_0 return ast end end @@ -3195,9 +3223,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return exprs2 end end - local function callable_3f(_367_0, ctype, callee) - local _368_ = _367_0 - local call_ast = _368_[1] + local function callable_3f(_376_0, ctype, callee) + local _377_ = _376_0 + local call_ast = _377_[1] if ("literal" == ctype) then return ("\"" == string.sub(callee, 1, 1)) else @@ -3205,20 +3233,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_function_call(ast, scope, parent, opts, compile1, len) - local _370_ = compile1(ast[1], scope, parent, {nval = 1})[1] - local callee = _370_[1] - local ctype = _370_["type"] + local _379_ = compile1(ast[1], scope, parent, {nval = 1})[1] + local callee = _379_[1] + local ctype = _379_["type"] local fargs = {} assert_compile(callable_3f(ast, ctype, callee), ("cannot call literal value " .. tostring(ast[1])), ast) for i = 2, len do local subexprs = nil - local _371_ + local _380_ if (i ~= len) then - _371_ = 1 + _380_ = 1 else - _371_ = nil + _380_ = nil end - subexprs = compile1(ast[i], scope, parent, {nval = _371_}) + subexprs = compile1(ast[i], scope, parent, {nval = _380_}) table.insert(fargs, subexprs[1]) if (i == len) then for j = 2, #subexprs do @@ -3256,13 +3284,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_varg(ast, scope, parent, opts) - local _376_ + local _385_ if scope.hashfn then - _376_ = "use $... in hashfn" + _385_ = "use $... in hashfn" else - _376_ = "unexpected vararg" + _385_ = "unexpected vararg" end - assert_compile(scope.vararg, _376_, ast) + assert_compile(scope.vararg, _385_, ast) return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast) end local function compile_sym(ast, scope, parent, opts) @@ -3279,31 +3307,31 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local view_opts = nil do local nan = tostring((0 / 0)) - local _379_ + local _388_ if (45 == nan:byte()) then - _379_ = "(0/0)" + _388_ = "(0/0)" else - _379_ = "(- (0/0))" + _388_ = "(- (0/0))" end - local _381_ + local _390_ if (45 == nan:byte()) then - _381_ = "(- (0/0))" + _390_ = "(- (0/0))" else - _381_ = "(0/0)" + _390_ = "(0/0)" end - view_opts = {["negative-infinity"] = "(-1/0)", ["negative-nan"] = _379_, infinity = "(1/0)", nan = _381_} + view_opts = {["negative-infinity"] = "(-1/0)", ["negative-nan"] = _388_, infinity = "(1/0)", nan = _390_} end local function compile_scalar(ast, _scope, parent, opts) local compiled = nil do - local _383_0 = type(ast) - if (_383_0 == "nil") then + local _392_0 = type(ast) + if (_392_0 == "nil") then compiled = "nil" - elseif (_383_0 == "boolean") then + elseif (_392_0 == "boolean") then compiled = tostring(ast) - elseif (_383_0 == "string") then + elseif (_392_0 == "string") then compiled = serialize_string(ast) - elseif (_383_0 == "number") then + elseif (_392_0 == "number") then compiled = view(ast, view_opts) else compiled = nil @@ -3316,8 +3344,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 _385_ = compile1(k, scope, parent, {nval = 1}) - local compiled = _385_[1] + local _394_ = compile1(k, scope, parent, {nval = 1}) + local compiled = _394_[1] return ("[" .. tostring(compiled) .. "]") end end @@ -3346,8 +3374,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct for k in utils.stablepairs(ast) do local val_19_ = nil if not keys[k] then - local _388_ = compile1(ast[k], scope, parent, {nval = 1}) - local v = _388_[1] + local _397_ = compile1(ast[k], scope, parent, {nval = 1}) + local v = _397_[1] val_19_ = string.format("%s = %s", escape_key(k), tostring(v)) else val_19_ = nil @@ -3379,12 +3407,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 _392_ = opts0 - local declaration = _392_["declaration"] - local forceglobal = _392_["forceglobal"] - local forceset = _392_["forceset"] - local isvar = _392_["isvar"] - local symtype = _392_["symtype"] + local _401_ = opts0 + local declaration = _401_["declaration"] + local forceglobal = _401_["forceglobal"] + local forceset = _401_["forceset"] + local isvar = _401_["isvar"] + local symtype = _401_["symtype"] local symtype0 = ("_" .. (symtype or "dst")) local setter = nil if declaration then @@ -3400,8 +3428,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return declare_local(symbol, scope, symbol, isvar, deferred_scope_changes) else local parts = (utils["multi-sym?"](raw) or {raw}) - local _394_ = parts - local first = _394_[1] + local _403_ = parts + local first = _403_[1] local meta = scope.symmeta[first] assert_compile(not raw:find(":"), "cannot set method sym", symbol) if ((#parts == 1) and not forceset) then @@ -3413,24 +3441,24 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not scope.symmeta[scope.unmanglings[raw]], ("global " .. raw .. " conflicts with local"), symbol) scope.manglings[raw] = global_mangling(raw) scope.unmanglings[global_mangling(raw)] = raw - local _397_ + local _406_ do - local _396_0 = utils.root.options - if (nil ~= _396_0) then - _396_0 = _396_0.allowedGlobals + local _405_0 = utils.root.options + if (nil ~= _405_0) then + _405_0 = _405_0.allowedGlobals end - _397_ = _396_0 + _406_ = _405_0 end - if _397_ then - local _400_ + if _406_ then + local _409_ do - local _399_0 = utils.root.options - if (nil ~= _399_0) then - _399_0 = _399_0.allowedGlobals + local _408_0 = utils.root.options + if (nil ~= _408_0) then + _408_0 = _408_0.allowedGlobals end - _400_ = _399_0 + _409_ = _408_0 end - table.insert(_400_, raw) + table.insert(_409_, raw) end end return symbol_to_expression(symbol, scope)[1] @@ -3485,11 +3513,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return emit(parent, setter:format(lname, exprs1(rightexprs)), left) end end - local function dynamic_set_target(_411_0) - local _412_ = _411_0 - local _ = _412_[1] - local target = _412_[2] - local keys = {(table.unpack or unpack)(_412_, 3)} + local function dynamic_set_target(_420_0) + local _421_ = _420_0 + local _ = _421_[1] + local target = _421_[2] + local keys = {(table.unpack or unpack)(_421_, 3)} assert_compile(utils["sym?"](target), "dynamic set needs symbol target", ast) assert_compile(next(keys), "dynamic set needs at least one key", ast) local keys0 = nil @@ -3540,10 +3568,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return nil end - 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 unpack_fn = "function (t, k)\n return ((getmetatable(t) or {}).__fennelrest\n or function (t, k) return {(table.unpack or unpack)(t, k)} end)(t, k)\n end" + local unpack_ks = "function (t, e)\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 end" local function destructure_kv_rest(s, v, left, excluded_keys, destructure1) local exclude_str = nil - local _417_ + local _426_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3554,25 +3583,25 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _417_ = tbl_17_ + _426_ = tbl_17_ end - exclude_str = table.concat(_417_, ", ") - local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_fn .. ")(%s, %s, {%s})"), "\n%s*", " "), s, tostring(v), exclude_str), "expression") + exclude_str = table.concat(_426_, ", ") + local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_ks .. ")(%s, {%s})"), "\n%s*", " "), s, exclude_str), "expression") return destructure1(v, {subexpr}, left) end local function destructure_rest(s, k, left, destructure1) local unpack_str = ("(" .. unpack_fn .. ")(%s, %s)") local formatted = string.format(string.gsub(unpack_str, "\n%s*", " "), s, k) local subexpr = utils.expr(formatted, "expression") - local function _419_() + local function _428_() local next_symbol = left[(k + 2)] return ((nil == next_symbol) or utils["sym?"](next_symbol, "&as")) end - assert_compile((utils["sequence?"](left) and _419_()), "expected rest argument before last parameter", left) + assert_compile((utils["sequence?"](left) and _428_()), "expected rest argument before last parameter", left) return destructure1(left[(k + 1)], {subexpr}, left) end local function optimize_table_destructure_3f(left, right) - local function _420_() + local function _429_() local all = next(left) for _, d in ipairs(left) do if not all then break end @@ -3580,24 +3609,25 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return all end - return (utils["sequence?"](left) and utils["sequence?"](right) and _420_()) + return (utils["sequence?"](left) and utils["sequence?"](right) and _429_()) end local function destructure_table(left, rightexprs, top_3f, destructure1, up1) + assert_compile((("table" == type(rightexprs)) and not utils["sym?"](rightexprs, "nil")), "could not destructure literal", left) if optimize_table_destructure_3f(left, rightexprs) then return destructure_values(utils.list(unpack(left)), utils.list(utils.sym("values"), unpack(rightexprs)), up1, destructure1) else local right = nil do - local _421_0 = nil + local _430_0 = nil if top_3f then - _421_0 = exprs1(compile1(from, scope, parent)) + _430_0 = exprs1(compile1(from, scope, parent)) else - _421_0 = exprs1(rightexprs) + _430_0 = exprs1(rightexprs) end - if (_421_0 == "") then + if (_430_0 == "") then right = "nil" - elseif (nil ~= _421_0) then - local right0 = _421_0 + elseif (nil ~= _430_0) then + local right0 = _430_0 right = right0 else right = nil @@ -3674,7 +3704,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function compile_asts(asts, options) local opts = utils.copy(options) - local scope = (opts.scope or make_scope(scopes.global)) + local scope = nil + if ("_COMPILER" == opts.scope) then + scope = scopes.compiler + elseif opts.scope then + scope = opts.scope + else + scope = make_scope(scopes.global) + end local chunk = {} if opts.requireAsInclude then scope.specials.require = require_include @@ -3682,8 +3719,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if opts.assertAsRepl then scope.macros.assert = scope.macros["assert-repl"] end - local _435_ = utils.root - _435_["set-reset"](_435_) + local _445_ = utils.root + _445_["set-reset"](_445_) 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)}) @@ -3716,21 +3753,21 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return compile_stream(parser["string-stream"](str, _3fopts), _3fopts) end local function compile(from, _3fopts) - local _438_0 = type(from) - if (_438_0 == "userdata") then - local function _439_() - local _440_0 = from:read(1) - if (nil ~= _440_0) then - return _440_0:byte() + local _448_0 = type(from) + if (_448_0 == "userdata") then + local function _449_() + local _450_0 = from:read(1) + if (nil ~= _450_0) then + return _450_0:byte() else - return _440_0 + return _450_0 end end - return compile_stream(_439_, _3fopts) - elseif (_438_0 == "function") then + return compile_stream(_449_, _3fopts) + elseif (_448_0 == "function") then return compile_stream(from, _3fopts) else - local _ = _438_0 + local _ = _448_0 return compile_asts({from}, _3fopts) end end @@ -3750,14 +3787,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 _445_() + local function _455_() if info.name then return ("'" .. info.name .. "'") else return "?" end end - return string.format("\9%s:%d: in function %s", info.short_src, info.currentline, _445_()) + return string.format("\9%s:%d: in function %s", info.short_src, info.currentline, _455_()) elseif (info.short_src == "(tail call)") then return " (tail call)" else @@ -3767,8 +3804,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local lua_getinfo = debug.getinfo local function traceback(_3fmsg, _3fstart) - local _448_0 = type(_3fmsg) - if ((_448_0 == "nil") or (_448_0 == "string")) then + local _458_0 = type(_3fmsg) + if ((_458_0 == "nil") or (_458_0 == "string")) then local msg = (_3fmsg or "") if ((msg:find("^%g+:%d+:%d+ Compile error:.*") or msg:find("^%g+:%d+:%d+ Parse error:.*")) and not utils["debug-on?"]("trace")) then return msg @@ -3784,11 +3821,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 _450_0 = lua_getinfo(level, "Sln") - if (_450_0 == nil) then + local _460_0 = lua_getinfo(level, "Sln") + if (_460_0 == nil) then done_3f = true - elseif (nil ~= _450_0) then - local info = _450_0 + elseif (nil ~= _460_0) then + local info = _460_0 table.insert(lines, traceback_frame(info)) end end @@ -3797,7 +3834,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(lines, "\n") end else - local _ = _448_0 + local _ = _458_0 return _3fmsg end end @@ -3814,14 +3851,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct for _, key in ipairs({"currentline", "linedefined", "lastlinedefined"}) do local mapped_value = nil do - local _455_0 = mapped - if (nil ~= _455_0) then - _455_0 = _455_0[info[key]] + local _465_0 = mapped + if (nil ~= _465_0) then + _465_0 = _465_0[info[key]] end - if (nil ~= _455_0) then - _455_0 = _455_0[2] + if (nil ~= _465_0) then + _465_0 = _465_0[2] end - mapped_value = _455_0 + mapped_value = _465_0 end if (info[key] and mapped_value) then info[key] = mapped_value @@ -3908,23 +3945,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not runtime_3f, "lists may only be used at compile time", form) return string.format(("setmetatable({filename=%s, line=%s, bytestart=%s, %s}" .. ", getmetatable(_G.list()))"), filename, (form.line or "nil"), (form.bytestart or "nil"), mixed_concat(mapped, ", ")) elseif utils["sequence?"](form) then - local mapped = quote_all(form) + local mapped_str = mixed_concat(quote_all(form), ", ") local source = getmetatable(form) local filename = nil if source.filename then - filename = string.format("%q", source.filename) + filename = ("%q"):format(source.filename) else filename = "nil" end - local _470_ - if source then - _470_ = source.line + if runtime_3f then + return string.format("{%s}", mapped_str) else - _470_ = "nil" + return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mapped_str, filename, (source.line or "nil"), "(getmetatable(_G.sequence()))['sequence']") end - return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _470_, "(getmetatable(_G.sequence()))['sequence']") elseif (type(form) == "table") then - local mapped = quote_all(form) local source = getmetatable(form) local filename = nil if source.filename then @@ -3932,14 +3966,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local function _473_() + local function _482_() if source then return source.line else return "nil" end end - return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _473_()) + return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(quote_all(form), ", "), filename, _482_()) elseif (type(form) == "string") then return serialize_string(form) else @@ -3949,10 +3983,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return {["apply-deferred-scope-changes"] = apply_deferred_scope_changes, ["check-binding-valid"] = check_binding_valid, ["compile-stream"] = compile_stream, ["compile-string"] = compile_string, ["declare-local"] = declare_local, ["do-quote"] = do_quote, ["global-allowed?"] = global_allowed_3f, ["global-mangling"] = global_mangling, ["global-unmangling"] = global_unmangling, ["keep-side-effects"] = keep_side_effects, ["make-scope"] = make_scope, ["require-include"] = require_include, ["symbol-to-expression"] = symbol_to_expression, assert = assert_compile, autogensym = autogensym, compile = compile, compile1 = compile1, destructure = destructure, emit = emit, gensym = gensym, getinfo = getinfo, macroexpand = macroexpand_2a, metadata = make_metadata(), scopes = scopes, sourcemap = sourcemap, traceback = traceback} end package.preload["fennel.friend"] = package.preload["fennel.friend"] or function(...) - local utils = require("fennel.utils") + local _193_ = require("fennel.utils") + local utils = _193_ + local unpack = _193_["unpack"] local utf8_ok_3f, utf8 = pcall(require, "utf8") local suggestions = {["$ and $... in hashfn are mutually exclusive"] = {"modifying the hashfn so it only contains $... or $, $1, $2, $3, etc"}, ["can't introduce (.*) here"] = {"declaring the local at the top-level"}, ["can't start multisym segment with a digit"] = {"removing the digit", "adding a non-digit before the digit"}, ["cannot call literal value"] = {"checking for typos", "checking for a missing function name", "making sure to use prefix operators, not infix"}, ["could not compile value of type "] = {"debugging the macro you're calling to return a list or table"}, ["could not read number (.*)"] = {"removing the non-digit character", "beginning the identifier with a non-digit if it is not meant to be a number"}, ["expected a function.* to call"] = {"removing the empty parentheses", "using square brackets if you want an empty table"}, ["expected at least one pattern/body pair"] = {"adding a pattern and a body to execute when the pattern matches"}, ["expected binding and iterator"] = {"making sure you haven't omitted a local name or iterator"}, ["expected binding sequence"] = {"placing a table here in square brackets containing identifiers to bind"}, ["expected body expression"] = {"putting some code in the body of this form after the bindings"}, ["expected each macro to be function"] = {"ensuring that the value for each key in your macros table contains a function", "avoid defining nested macro tables"}, ["expected even number of name/value bindings"] = {"finding where the identifier or value is missing"}, ["expected even number of pattern/body pairs"] = {"checking that every pattern has a body to go with it", "adding _ before the final body"}, ["expected even number of values in table literal"] = {"removing a key", "adding a value"}, ["expected local"] = {"looking for a typo", "looking for a local which is used out of its scope"}, ["expected macros to be table"] = {"ensuring your macro definitions return a table"}, ["expected parameters"] = {"adding function parameters as a list of identifiers in brackets"}, ["expected range to include start and stop"] = {"adding missing arguments"}, ["expected rest argument before last parameter"] = {"moving & to right before the final identifier when destructuring"}, ["expected symbol for function parameter: (.*)"] = {"changing %s to an identifier instead of a literal value"}, ["expected var (.*)"] = {"declaring %s using var instead of let/local", "introducing a new local instead of changing the value of %s"}, ["expected vararg as last parameter"] = {"moving the \"...\" to the end of the parameter list"}, ["expected whitespace before opening delimiter"] = {"adding whitespace"}, ["global (.*) conflicts with local"] = {"renaming local %s"}, ["invalid character: (.)"] = {"deleting or replacing %s", "avoiding reserved characters like \", \\, ', ~, ;, @, `, and comma"}, ["local (.*) was overshadowed by a special form or macro"] = {"renaming local %s"}, ["macro not found in macro module"] = {"checking the keys of the imported macro module's returned table"}, ["macro tried to bind (.*) without gensym"] = {"changing to %s# when introducing identifiers inside macros"}, ["malformed multisym"] = {"ensuring each period or colon is not followed by another period or colon"}, ["may only be used at compile time"] = {"moving this to inside a macro if you need to manipulate symbols/lists", "using square brackets instead of parens to construct a table"}, ["method must be last component"] = {"using a period instead of a colon for field access", "removing segments after the colon", "making the method call, then looking up the field on the result"}, ["mismatched closing delimiter (.), expected (.)"] = {"replacing %s with %s", "deleting %s", "adding matching opening delimiter earlier"}, ["missing subject"] = {"adding an item to operate on"}, ["multisym method calls may only be in call position"] = {"using a period instead of a colon to reference a table's fields", "putting parens around this"}, ["tried to reference a macro without calling it"] = {"renaming the macro so as not to conflict with locals"}, ["tried to reference a special form without calling it"] = {"making sure to use prefix operators, not infix", "wrapping the special in a function if you need it to be first class"}, ["tried to use unquote outside quote"] = {"moving the form to inside a quoted form", "removing the comma"}, ["tried to use vararg with operator"] = {"accumulating over the operands"}, ["unable to bind (.*)"] = {"replacing the %s with an identifier"}, ["unexpected arguments"] = {"removing an argument", "checking for typos"}, ["unexpected closing delimiter (.)"] = {"deleting %s", "adding matching opening delimiter earlier"}, ["unexpected iterator clause"] = {"removing an argument", "checking for typos"}, ["unexpected multi symbol (.*)"] = {"removing periods or colons from %s"}, ["unexpected vararg"] = {"putting \"...\" at the end of the fn parameters if the vararg was intended"}, ["unknown identifier: (.*)"] = {"looking to see if there's a typo", "using the _G table instead, eg. _G.%s if you really want a global", "moving this code to somewhere that %s is in scope", "binding %s as a local in the scope of this code"}, ["unused local (.*)"] = {"renaming the local to _%s if it is meant to be unused", "fixing a typo so %s is used", "disabling the linter which checks for unused locals"}, ["use of global (.*) is aliased by a local"] = {"renaming local %s", "refer to the global using _G.%s instead of directly"}} - local unpack = (table.unpack or _G.unpack) local function suggest(msg) local s = nil for pat, sug in pairs(suggestions) do @@ -3992,13 +4027,13 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( return error(..., 0) end end - local function _190_() + local function _197_() for _ = 2, line do f:read() end return f:read() end - return close_handlers_10_(_G.xpcall(_190_, (package.loaded.fennel or debug).traceback)) + return close_handlers_10_(_G.xpcall(_197_, (package.loaded.fennel or debug).traceback)) end end local function sub(str, start, _end) @@ -4014,8 +4049,8 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( if ((opts and (false == opts["error-pinpoint"])) or (os and os.getenv and os.getenv("NO_COLOR"))) then return codeline else - local _193_ = (opts or {}) - local error_pinpoint = _193_["error-pinpoint"] + local _200_ = (opts or {}) + local error_pinpoint = _200_["error-pinpoint"] local endcol = (_3fendcol or col) local eol = nil if utf8_ok_3f then @@ -4023,19 +4058,19 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( else eol = string.len(codeline) end - local _195_ = (error_pinpoint or {"\27[7m", "\27[0m"}) - local open = _195_[1] - local close = _195_[2] + local _202_ = (error_pinpoint or {"\27[7m", "\27[0m"}) + local open = _202_[1] + local close = _202_[2] return (sub(codeline, 1, col) .. open .. sub(codeline, (col + 1), (endcol + 1)) .. close .. sub(codeline, (endcol + 2), eol)) end end - local function friendly_msg(msg, _197_0, source, opts) - local _198_ = _197_0 - local col = _198_["col"] - local endcol = _198_["endcol"] - local endline = _198_["endline"] - local filename = _198_["filename"] - local line = _198_["line"] + local function friendly_msg(msg, _204_0, source, opts) + local _205_ = _204_0 + local col = _205_["col"] + local endcol = _205_["endcol"] + local endline = _205_["endline"] + local filename = _205_["filename"] + local line = _205_["line"] local ok, codeline = pcall(read_line, filename, line, source) local endcol0 = nil if (ok and codeline and (line ~= endline)) then @@ -4058,10 +4093,10 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( end local function assert_compile(condition, msg, ast, source, opts) if not condition then - local _202_ = utils["ast-source"](ast) - local col = _202_["col"] - local filename = _202_["filename"] - local line = _202_["line"] + local _209_ = utils["ast-source"](ast) + local col = _209_["col"] + local filename = _209_["filename"] + local line = _209_["line"] error(friendly_msg(("%s:%s:%s: Compile error: %s"):format((filename or "unknown"), (line or "?"), (col or "?"), msg), utils["ast-source"](ast), source, opts), 0) end return condition @@ -4072,41 +4107,37 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( return {["assert-compile"] = assert_compile, ["parse-error"] = parse_error} end package.preload["fennel.parser"] = package.preload["fennel.parser"] or function(...) - local utils = require("fennel.utils") + local _192_ = require("fennel.utils") + local utils = _192_ + local unpack = _192_["unpack"] local friend = require("fennel.friend") - local unpack = (table.unpack or _G.unpack) local function granulate(getchunk) local c, index, done_3f = "", 1, false - local function _204_(parser_state) + local function _211_(parser_state) if not done_3f then if (index <= #c) then local b = c:byte(index) index = (index + 1) return b else - local _205_0 = getchunk(parser_state) - local function _206_() - local char = _205_0 - return (char ~= "") - end - if ((nil ~= _205_0) and _206_()) then - local char = _205_0 - c = char - index = 2 + local _212_0 = getchunk(parser_state) + if (nil ~= _212_0) then + local input = _212_0 + c, index = input, 2 return c:byte() else - local _ = _205_0 + local _ = _212_0 done_3f = true return nil end end end end - local function _210_() + local function _216_() c = "" return nil end - return _204_, _210_ + return _211_, _216_ end local function string_stream(str, _3foptions) local str0 = str:gsub("^#!", ";;") @@ -4114,12 +4145,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( _3foptions.source = str0 end local index = 1 - local function _212_() + local function _218_() local r = str0:byte(index) index = (index + 1) return r end - return _212_ + return _218_ end local delims = {[123] = 125, [125] = true, [40] = 41, [41] = true, [91] = 93, [93] = true} local function sym_char_3f(b) @@ -4141,12 +4172,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( local function char_starter_3f(b) return (((1 < b) and (b < 127)) or ((192 < b) and (b < 247))) end - local function parser_fn(getbyte, filename, _215_0) - local _216_ = _215_0 - local options = _216_ - local comments = _216_["comments"] - local source = _216_["source"] - local unfriendly = _216_["unfriendly"] + local function parser_fn(getbyte, filename, _221_0) + local _222_ = _221_0 + local options = _222_ + local comments = _222_["comments"] + local source = _222_["source"] + local unfriendly = _222_["unfriendly"] local stack = {} local line, byteindex, col, prev_col, lastb = 1, 0, 0, 0, nil local function ungetb(ub) @@ -4178,15 +4209,18 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return r end + local function warn(...) + return (options.warn or utils.warn)(...) + end local function whitespace_3f(b) - local function _224_() - local _223_0 = options.whitespace - if (nil ~= _223_0) then - _223_0 = _223_0[b] + local function _230_() + local _229_0 = options.whitespace + if (nil ~= _229_0) then + _229_0 = _229_0[b] end - return _223_0 + return _229_0 end - return ((b == 32) or ((9 <= b) and (b <= 13)) or _224_()) + return ((b == 32) or ((9 <= b) and (b <= 13)) or _230_()) end local function parse_error(msg, _3fcol_adjust) local col0 = (col + (_3fcol_adjust or -1)) @@ -4209,31 +4243,31 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( whitespace_since_dispatch = false local v0 = nil do - local _228_0 = utils["hook-opts"]("parse-form", options, v, _3fsource, _3fraw, stack) - if (nil ~= _228_0) then - local hookv = _228_0 + local _234_0 = utils["hook-opts"]("parse-form", options, v, _3fsource, _3fraw, stack) + if (nil ~= _234_0) then + local hookv = _234_0 v0 = hookv else - local _ = _228_0 + local _ = _234_0 v0 = v end end - local _230_0 = stack[#stack] - if (_230_0 == nil) then + local _236_0 = stack[#stack] + if (_236_0 == nil) then retval, done_3f = v0, true return nil - elseif ((_G.type(_230_0) == "table") and (nil ~= _230_0.prefix)) then - local prefix = _230_0.prefix + elseif ((_G.type(_236_0) == "table") and (nil ~= _236_0.prefix)) then + local prefix = _236_0.prefix local source0 = nil do - local _231_0 = table.remove(stack) - set_source_fields(_231_0) - source0 = _231_0 + local _237_0 = table.remove(stack) + set_source_fields(_237_0) + source0 = _237_0 end local list = utils.list(utils.sym(prefix, source0), v0) return dispatch(utils.copy(source0, list)) - elseif (nil ~= _230_0) then - local top = _230_0 + elseif (nil ~= _236_0) then + local top = _236_0 return table.insert(top, v0) end end @@ -4242,9 +4276,9 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( do local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _233_0 in ipairs(stack) do - local _234_ = _233_0 - local closer = _234_["closer"] + for _, _239_0 in ipairs(stack) do + local _240_ = _239_0 + local closer = _240_["closer"] local val_19_ = closer if (nil ~= val_19_) then i_18_ = (i_18_ + 1) @@ -4253,13 +4287,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end closers = tbl_17_ end - local _236_ + local _242_ if (#stack == 1) then - _236_ = "" + _242_ = "" else - _236_ = "s" + _242_ = "s" end - return parse_error(string.format("expected closing delimiter%s %s", _236_, string.char(unpack(closers))), 0) + return parse_error(string.format("expected closing delimiter%s %s", _242_, string.char(unpack(closers))), 0) end local function skip_whitespace(b, close_table) if (b and whitespace_3f(b)) then @@ -4277,11 +4311,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 _239_() + local function _245_() table.insert(contents, string.char(b)) return contents end - return parse_comment(getb(), _239_()) + return parse_comment(getb(), _245_()) elseif comments then ungetb(10) return dispatch(utils.comment(table.concat(contents), {filename = filename, line = line})) @@ -4307,12 +4341,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 _243_0 = comments0[index] - if (nil ~= _243_0) then - local existing = _243_0 + local _249_0 = comments0[index] + if (nil ~= _249_0) then + local existing = _249_0 return table.insert(existing, node) else - local _ = _243_0 + local _ = _249_0 comments0[index] = {node} return nil end @@ -4391,16 +4425,16 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local state0 = nil do - local _254_0 = {state, b} - if ((_G.type(_254_0) == "table") and (_254_0[1] == "base") and (_254_0[2] == 92)) then + local _260_0 = {state, b} + if ((_G.type(_260_0) == "table") and (_260_0[1] == "base") and (_260_0[2] == 92)) then state0 = "backslash" - elseif ((_G.type(_254_0) == "table") and (_254_0[1] == "base") and (_254_0[2] == 34)) then + elseif ((_G.type(_260_0) == "table") and (_260_0[1] == "base") and (_260_0[2] == 34)) then state0 = "done" - elseif ((_G.type(_254_0) == "table") and (_254_0[1] == "backslash") and (_254_0[2] == 10)) then + elseif ((_G.type(_260_0) == "table") and (_260_0[1] == "backslash") and (_260_0[2] == 10)) then table.remove(chars, (#chars - 1)) state0 = "base" else - local _ = _254_0 + local _ = _260_0 state0 = "base" end end @@ -4415,7 +4449,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local function parse_string(source0) if not whitespace_since_dispatch then - utils.warn("expected whitespace before string", nil, filename, line) + warn("expected whitespace before string", nil, filename, line) end table.insert(stack, {closer = 34}) local chars = {"\""} @@ -4425,11 +4459,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 _259_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) - if (nil ~= _259_0) then - local load_fn = _259_0 + local _265_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) + if (nil ~= _265_0) then + local load_fn = _265_0 return dispatch(load_fn(), source0, raw) - elseif (_259_0 == nil) then + elseif (_265_0 == nil) then return parse_error(("Invalid string: " .. raw)) end end @@ -4466,13 +4500,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( dispatch((tonumber(trimmed) or parse_error(("could not read number \"" .. rawstr .. "\""))), source0, rawstr) return true else - local _265_0 = tonumber(trimmed) - if (nil ~= _265_0) then - local x = _265_0 + local _271_0 = tonumber(trimmed) + if (nil ~= _271_0) then + local x = _271_0 dispatch(x, source0, rawstr) return true else - local _ = _265_0 + local _ = _271_0 return false end end @@ -4491,7 +4525,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( parse_error(("method must be last component of multisym: " .. rawstr), col_adjust(":.+[%.:]")) end if not whitespace_since_dispatch then - utils.warn("expected whitespace before token", nil, filename, line) + warn("expected whitespace before token", nil, filename, line) end return rawstr end @@ -4546,11 +4580,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return parse_loop(skip_whitespace(getb(), close_table)) end - local function _273_() + local function _279_() stack, line, byteindex, col, lastb = {}, 1, 0, 0, ((lastb ~= 10) and lastb) return nil end - return parse_stream, _273_ + return parse_stream, _279_ end local function parser(stream_or_string, _3ffilename, _3foptions) local filename = (_3ffilename or "unknown") @@ -4567,7 +4601,7 @@ end local utils = nil package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local type_order = {["function"] = 5, boolean = 2, number = 1, string = 3, table = 4, thread = 7, userdata = 6} - local default_opts = {["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["escape-newlines?"] = false, ["line-length"] = 80, ["max-sparse-gap"] = 10, ["metamethod?"] = true, ["one-line?"] = false, ["prefer-colon?"] = false, ["utf8?"] = true, depth = 128} + local default_opts = {["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["escape-newlines?"] = false, ["line-length"] = 80, ["max-sparse-gap"] = 1, ["metamethod?"] = true, ["one-line?"] = false, ["prefer-colon?"] = false, ["utf8?"] = true, depth = 128} local lua_pairs = pairs local lua_ipairs = ipairs local function pairs(t) @@ -4703,11 +4737,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) return nil end local function table_kv_pairs(t, options) + if (("number" ~= type(options["max-sparse-gap"])) or (options["max-sparse-gap"] ~= math.floor(options["max-sparse-gap"]))) then + error(("max-sparse-gap must be an integer: got '%s'"):format(tostring(options["max-sparse-gap"]))) + end local assoc_3f = false local kv = {} local insert = table.insert for k, v in pairs(t) do - if ((type(k) ~= "number") or (k < 1)) then + if (("number" ~= type(k)) or (k < 1) or (k ~= math.floor(k))) then assoc_3f = true end insert(kv, {k, v}) @@ -4723,14 +4760,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) if (length_2a(kv) == 0) then return kv, "empty" else - local function _31_() + local function _32_() if assoc_3f then return "table" else return "seq" end end - return kv, _31_() + return kv, _32_() end end local function count_table_appearances(t, appearances) @@ -4783,14 +4820,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix, last_comment_3f) local indent_str = ("\n" .. string.rep(" ", indent)) local open = nil - local function _38_() + local function _39_() if ("seq" == table_type) then return "[" else return "{" end end - open = ((prefix or "") .. _38_()) + open = ((prefix or "") .. _39_()) local close = nil if ("seq" == table_type) then close = "]" @@ -4799,14 +4836,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end local oneline = (open .. table.concat(elements, " ") .. close) if (not getopt(options, "one-line?") and (multiline_3f or (options["line-length"] < (indent + length_2a(oneline))) or last_comment_3f)) then - local function _40_() + local function _41_() if last_comment_3f then return indent_str else return "" end end - return (open .. table.concat(elements, indent_str) .. _40_() .. close) + return (open .. table.concat(elements, indent_str) .. _41_() .. close) else return oneline end @@ -4841,10 +4878,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) if getopt(options, "utf8?") then slength = utf8_len else - local function _43_(_241) + local function _44_(_241) return #_241 end - slength = _43_ + slength = _44_ end local prefix = nil if visible_cycle_3f0 then @@ -4857,10 +4894,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local options0 = normalize_opts(options) local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _46_0 in ipairs(kv) do - local _47_ = _46_0 - local k = _47_[1] - local v = _47_[2] + for _, _47_0 in ipairs(kv) do + local _48_ = _47_0 + local k = _48_[1] + local v = _48_[2] local val_19_ = nil do local k0 = pp(k, options0, (indent0 + 1), true) @@ -4901,10 +4938,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local options0 = normalize_opts(options) local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _51_0 in ipairs(kv) do - local _52_ = _51_0 - local _0 = _52_[1] - local v = _52_[2] + for _, _52_0 in ipairs(kv) do + local _53_ = _52_0 + local _0 = _53_[1] + local v = _53_[2] local val_19_ = nil do local v0 = pp(v, options0, indent0) @@ -4930,7 +4967,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end else local oneline = nil - local _56_ + local _57_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -4941,9 +4978,9 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) tbl_17_[i_18_] = val_19_ end end - _56_ = tbl_17_ + _57_ = tbl_17_ end - oneline = table.concat(_56_, " ") + oneline = table.concat(_57_, " ") if (not getopt(options, "one-line?") and (force_multi_line_3f or oneline:find("\n") or (options["line-length"] < (indent + length_2a(oneline))))) then return table.concat(lines, ("\n" .. string.rep(" ", indent))) else @@ -4960,10 +4997,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end else local _ = nil - local function _61_(_241) + local function _62_(_241) return visible_cycle_3f(_241, options) end - options["visible-cycle?"] = _61_ + options["visible-cycle?"] = _62_ _ = nil local lines, force_multi_line_3f = nil, nil do @@ -4971,13 +5008,13 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) lines, force_multi_line_3f = metamethod(t, pp, options0, indent) end options["visible-cycle?"] = nil - local _62_0 = type(lines) - if (_62_0 == "string") then + local _63_0 = type(lines) + if (_63_0 == "string") then return lines - elseif (_62_0 == "table") then + elseif (_63_0 == "table") then return concat_lines(lines, options, indent, force_multi_line_3f) else - local _0 = _62_0 + local _0 = _63_0 return error("__fennelview metamethod must return a table of lines") end end @@ -4986,40 +5023,40 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) options.level = (options.level + 1) local x0 = nil do - local _65_0 = nil + local _66_0 = nil if getopt(options, "metamethod?") then - local _66_0 = x - if (nil ~= _66_0) then - local _67_0 = getmetatable(_66_0) - if (nil ~= _67_0) then - _65_0 = _67_0.__fennelview + local _67_0 = x + if (nil ~= _67_0) then + local _68_0 = getmetatable(_67_0) + if (nil ~= _68_0) then + _66_0 = _68_0.__fennelview else - _65_0 = _67_0 + _66_0 = _68_0 end else - _65_0 = _66_0 + _66_0 = _67_0 end else - _65_0 = nil + _66_0 = nil end - if (nil ~= _65_0) then - local metamethod = _65_0 + if (nil ~= _66_0) then + local metamethod = _66_0 x0 = pp_metamethod(x, metamethod, options, indent) else - local _ = _65_0 - local _71_0, _72_0 = table_kv_pairs(x, options) - if (true and (_72_0 == "empty")) then - local _0 = _71_0 + local _ = _66_0 + local _72_0, _73_0 = table_kv_pairs(x, options) + if (true and (_73_0 == "empty")) then + local _0 = _72_0 if getopt(options, "empty-as-sequence?") then x0 = "[]" else x0 = "{}" end - elseif ((nil ~= _71_0) and (_72_0 == "table")) then - local kv = _71_0 + elseif ((nil ~= _72_0) and (_73_0 == "table")) then + local kv = _72_0 x0 = pp_associative(x, kv, options, indent) - elseif ((nil ~= _71_0) and (_72_0 == "seq")) then - local kv = _71_0 + elseif ((nil ~= _72_0) and (_73_0 == "seq")) then + local kv = _72_0 x0 = pp_sequence(x, kv, options, indent) else x0 = nil @@ -5031,7 +5068,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end local function exponential_notation(n, fallback) local s = nil - for i = 0, 308 do + for i = 0, 99 do if s then break end local s0 = string.format(("%." .. i .. "e"), n) if (n == tonumber(s0)) then @@ -5058,7 +5095,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) val = (options.nan or ".nan") end elseif (math.floor(n) == n) then - local s1 = string.format("%.f", n) + local s1 = string.format("%.0f", n) if (s1 == inf_str) then val = (options.infinity or ".inf") elseif (s1 == neg_inf_str) then @@ -5071,8 +5108,8 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) else val = tostring(n) end - local _81_0 = string.gsub(val, ",", ".") - return _81_0 + local _82_0 = string.gsub(val, ",", ".") + return _82_0 end local function colon_string_3f(s) return s:find("^[-%w?^_!$%&*+./|<=>]+$") @@ -5090,12 +5127,12 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local ret = nil for _, init0 in ipairs(inits) do if ret then break end - ret = (byte and (function(_82_,_83_,_84_) return (_82_ <= _83_) and (_83_ <= _84_) end)(init0["min-byte"],byte,init0["max-byte"]) and init0) + ret = (byte and (function(_83_,_84_,_85_) return (_83_ <= _84_) and (_84_ <= _85_) end)(init0["min-byte"],byte,init0["max-byte"]) and init0) end init = ret end local code = nil - local function _85_() + local function _86_() local code0 = nil if init then code0 = (byte - init["min-byte"]) @@ -5108,8 +5145,8 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end return code0 end - code = (init and _85_()) - if (code and (function(_87_,_88_,_89_) return (_87_ <= _88_) and (_88_ <= _89_) end)(init["min-code"],code,init["max-code"]) and not ((55296 <= code) and (code <= 57343))) then + code = (init and _86_()) + if (code and (function(_88_,_89_,_90_) return (_88_ <= _89_) and (_89_ <= _90_) end)(init["min-code"],code,init["max-code"]) and not ((55296 <= code) and (code <= 57343))) then return init.len end end @@ -5136,16 +5173,16 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local esc_newline_3f = ((len < 2) or (getopt(options, "escape-newlines?") and (len < (options["line-length"] - indent)))) local byte_escape = (getopt(options, "byte-escape") or default_byte_escape) local escs = nil - local _93_ + local _94_ if esc_newline_3f then - _93_ = "\\n" + _94_ = "\\n" else - _93_ = "\n" + _94_ = "\n" end - local function _95_(_241, _242) + local function _96_(_241, _242) return byte_escape(_242:byte(), options) end - escs = setmetatable({["\""] = "\\\"", ["\11"] = "\\v", ["\12"] = "\\f", ["\13"] = "\\r", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\\"] = "\\\\", ["\n"] = _93_}, {__index = _95_}) + escs = setmetatable({["\""] = "\\\"", ["\11"] = "\\v", ["\12"] = "\\f", ["\13"] = "\\r", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\\"] = "\\\\", ["\n"] = _94_}, {__index = _96_}) local str0 = ("\"" .. str:gsub("[%c\\\"]", escs) .. "\"") if getopt(options, "utf8?") then return utf8_escape(str0, options) @@ -5174,7 +5211,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end return defaults end - local function _98_(x, options, indent, colon_3f) + local function _99_(x, options, indent, colon_3f) local indent0 = (indent or 0) local options0 = (options or make_options(x)) local x0 = nil @@ -5184,19 +5221,19 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) x0 = x end local tv = type(x0) - local function _101_() - local _100_0 = getmetatable(x0) - if ((_G.type(_100_0) == "table") and true) then - local __fennelview = _100_0.__fennelview + local function _102_() + local _101_0 = getmetatable(x0) + if ((_G.type(_101_0) == "table") and true) then + local __fennelview = _101_0.__fennelview return __fennelview end end - if ((tv == "table") or ((tv == "userdata") and _101_())) then + if ((tv == "table") or ((tv == "userdata") and _102_())) then return pp_table(x0, options0, indent0) elseif (tv == "number") then return number__3estring(x0, options0) else - local function _103_() + local function _104_() if (colon_3f ~= nil) then return colon_3f elseif ("function" == type(options0["prefer-colon?"])) then @@ -5205,7 +5242,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) return getopt(options0, "prefer-colon?") end end - if ((tv == "string") and colon_string_3f(x0) and _103_()) then + if ((tv == "string") and colon_string_3f(x0) and _104_()) then return (":" .. x0) elseif (tv == "string") then return pp_string(x0, options0, indent0) @@ -5216,7 +5253,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end end end - pp = _98_ + pp = _99_ local function _view(x, _3foptions) return pp(x, make_options(x, _3foptions), 0) end @@ -5224,7 +5261,28 @@ 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.5.1" + local version = "1.5.3" + local unpack = (table.unpack or _G.unpack) + local pack = nil + local function _106_(...) + local _107_0 = {...} + _107_0["n"] = select("#", ...) + return _107_0 + end + pack = (table.pack or _106_) + local maxn = nil + local function _108_(_241) + local max = 0 + for k in pairs(_241) do + if (("number" == type(k)) and (max < k)) then + max = k + else + max = max + end + end + return max + end + maxn = (table.maxn or _108_) 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 @@ -5261,32 +5319,32 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local len = nil do - local _108_0, _109_0 = pcall(require, "utf8") - if ((_108_0 == true) and (nil ~= _109_0)) then - local utf8 = _109_0 + local _113_0, _114_0 = pcall(require, "utf8") + if ((_113_0 == true) and (nil ~= _114_0)) then + local utf8 = _114_0 len = utf8.len else - local _ = _108_0 + local _ = _113_0 len = string.len end end local kv_order = {boolean = 2, number = 1, string = 3, table = 4} local function kv_compare(a, b) - local _111_0, _112_0 = type(a), type(b) - if (((_111_0 == "number") and (_112_0 == "number")) or ((_111_0 == "string") and (_112_0 == "string"))) then + local _116_0, _117_0 = type(a), type(b) + if (((_116_0 == "number") and (_117_0 == "number")) or ((_116_0 == "string") and (_117_0 == "string"))) then return (a < b) else - local function _113_() - local a_t = _111_0 - local b_t = _112_0 + local function _118_() + local a_t = _116_0 + local b_t = _117_0 return (a_t ~= b_t) end - if (((nil ~= _111_0) and (nil ~= _112_0)) and _113_()) then - local a_t = _111_0 - local b_t = _112_0 + if (((nil ~= _116_0) and (nil ~= _117_0)) and _118_()) then + local a_t = _116_0 + local b_t = _117_0 return ((kv_order[a_t] or 5) < (kv_order[b_t] or 5)) else - local _ = _111_0 + local _ = _116_0 return (tostring(a) < tostring(b)) end end @@ -5318,20 +5376,20 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. local function stablepairs(t) local mt_keys = nil do - local _117_0 = getmetatable(t) - if (nil ~= _117_0) then - _117_0 = _117_0.keys + local _122_0 = getmetatable(t) + if (nil ~= _122_0) then + _122_0 = _122_0.keys end - mt_keys = _117_0 + mt_keys = _122_0 end local succ, prev, first_mt = nil, nil, nil - local function _119_(_241) + local function _124_(_241) return t[_241] end - succ, prev, first_mt = add_stable_keys({}, nil, (mt_keys or {}), _119_) + succ, prev, first_mt = add_stable_keys({}, nil, (mt_keys or {}), _124_) local pairs_keys = nil do - local _120_0 = nil + local _125_0 = nil do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -5342,10 +5400,10 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_17_[i_18_] = val_19_ end end - _120_0 = tbl_17_ + _125_0 = tbl_17_ end - table.sort(_120_0, kv_compare) - pairs_keys = _120_0 + table.sort(_125_0, kv_compare) + pairs_keys = _125_0 end local succ0, _, first_after_mt = add_stable_keys(succ, prev, pairs_keys) local first = nil @@ -5355,19 +5413,19 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. first = first_mt end local function stablenext(tbl, key) - local _123_0 = nil + local _128_0 = nil if (key == nil) then - _123_0 = first + _128_0 = first else - _123_0 = succ0[key] + _128_0 = succ0[key] end - if (nil ~= _123_0) then - local next_key = _123_0 - local _125_0 = tbl[next_key] - if (_125_0 ~= nil) then - return next_key, _125_0 + if (nil ~= _128_0) then + local next_key = _128_0 + local _130_0 = tbl[next_key] + if (_130_0 ~= nil) then + return next_key, _130_0 else - return _125_0 + return _130_0 end end end @@ -5398,27 +5456,16 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return tbl_14_ end local function member_3f(x, tbl, _3fn) - local _131_0 = tbl[(_3fn or 1)] - if (_131_0 == x) then + local _136_0 = tbl[(_3fn or 1)] + if (_136_0 == x) then return true - elseif (_131_0 == nil) then + elseif (_136_0 == nil) then return nil else - local _ = _131_0 + local _ = _136_0 return member_3f(x, tbl, ((_3fn or 1) + 1)) end end - local function maxn(tbl) - local max = 0 - for k in pairs(tbl) do - if ("number" == type(k)) then - max = math.max(max, k) - else - max = max - end - end - return max - end local function every_3f(t, predicate) local result = true for _, item in ipairs(t) do @@ -5439,9 +5486,9 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. seen[next_state] = true return next_state, value else - local _134_0 = getmetatable(t) - if ((_G.type(_134_0) == "table") and true) then - local __index = _134_0.__index + local _138_0 = getmetatable(t) + if ((_G.type(_138_0) == "table") and true) then + local __index = _138_0.__index if ("table" == type(__index)) then t = __index return allpairs_next(t) @@ -5475,9 +5522,6 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return ("(" .. table.concat(viewed, " ") .. ")") end - local function comment_view(c) - return c, true - end local function sym_3d(a, b) return ((deref(a) == deref(b)) and (getmetatable(a) == getmetatable(b))) end @@ -5486,19 +5530,23 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local symbol_mt = {"SYMBOL", __eq = sym_3d, __fennelview = deref, __lt = sym_3c, __tostring = deref} local expr_mt = nil - local function _140_(x) + local function _144_(x) return tostring(deref(x)) end - expr_mt = {"EXPR", __tostring = _140_} + expr_mt = {"EXPR", __tostring = _144_} local list_mt = {"LIST", __fennelview = list__3estring, __tostring = list__3estring} - local comment_mt = {"COMMENT", __eq = sym_3d, __fennelview = comment_view, __lt = sym_3c, __tostring = deref} + local comment_mt = nil + local function _145_(_241) + return _241 + end + comment_mt = {"COMMENT", __eq = sym_3d, __fennelview = _145_, __lt = sym_3c, __tostring = deref} local sequence_marker = {"SEQUENCE"} local varg_mt = {"VARARG", __fennelview = deref, __tostring = deref} local getenv = nil - local function _141_() + local function _146_() return nil end - getenv = ((os and os.getenv) or _141_) + getenv = ((os and os.getenv) or _146_) local function debug_on_3f(flag) local level = (getenv("FENNEL_DEBUG") or "") return ((level == "all") or level:find(flag)) @@ -5507,7 +5555,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return setmetatable({...}, list_mt) end local function sym(str, _3fsource) - local _142_ + local _147_ do local tbl_14_ = {str} for k, v in pairs((_3fsource or {})) do @@ -5521,12 +5569,12 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_14_[k_15_] = v_16_ end end - _142_ = tbl_14_ + _147_ = tbl_14_ end - return setmetatable(_142_, symbol_mt) + return setmetatable(_147_, symbol_mt) end local function sequence(...) - local function _145_(seq, view0, inspector, indent) + local function _150_(seq, view0, inspector, indent) local opts = nil do inspector["empty-as-sequence?"] = {after = inspector["empty-as-sequence?"], once = true} @@ -5535,19 +5583,19 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return view0(seq, opts, indent) end - return setmetatable({...}, {__fennelview = _145_, sequence = sequence_marker}) + return setmetatable({...}, {__fennelview = _150_, sequence = sequence_marker}) end local function expr(strcode, etype) return setmetatable({strcode, type = etype}, expr_mt) end local function comment_2a(contents, _3fsource) - local _146_ = (_3fsource or {}) - local filename = _146_["filename"] - local line = _146_["line"] + local _151_ = (_3fsource or {}) + local filename = _151_["filename"] + local line = _151_["line"] return setmetatable({contents, filename = filename, line = line}, comment_mt) end local function varg(_3fsource) - local _147_ + local _152_ do local tbl_14_ = {"..."} for k, v in pairs((_3fsource or {})) do @@ -5561,9 +5609,9 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_14_[k_15_] = v_16_ end end - _147_ = tbl_14_ + _152_ = tbl_14_ end - return setmetatable(_147_, varg_mt) + return setmetatable(_152_, varg_mt) end local function expr_3f(x) return ((type(x) == "table") and (getmetatable(x) == expr_mt) and x) @@ -5613,7 +5661,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. elseif (type(str) ~= "string") then return false else - local function _153_() + local function _158_() local parts = {} for part in str:gmatch("[^%.%:]+[%.%:]?") do local last_char = part:sub(-1) @@ -5628,7 +5676,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return (next(parts) and parts) end - return ((str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte() ~= string.byte(":")) and (str:byte(-1) ~= string.byte(".")) and (str:byte(-1) ~= string.byte(":")) and _153_()) + return ((str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte() ~= string.byte(":")) and (str:byte(-1) ~= string.byte(".")) and (str:byte(-1) ~= string.byte(":")) and _158_()) end end local function call_of_3f(ast, callee) @@ -5654,15 +5702,15 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return root end local root = nil - local function _158_() + local function _163_() end - root = {chunk = nil, options = nil, reset = _158_, scope = nil} - root["set-reset"] = function(_159_0) - local _160_ = _159_0 - local chunk = _160_["chunk"] - local options = _160_["options"] - local reset = _160_["reset"] - local scope = _160_["scope"] + root = {chunk = nil, options = nil, reset = _163_, scope = nil} + root["set-reset"] = function(_164_0) + local _165_ = _164_0 + local chunk = _165_["chunk"] + local options = _165_["options"] + local reset = _165_["reset"] + local scope = _165_["scope"] root.reset = function() root.chunk, root.scope, root.options, root.reset = chunk, scope, options, reset return nil @@ -5671,17 +5719,17 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local lua_keywords = {["and"] = true, ["break"] = true, ["do"] = true, ["else"] = true, ["elseif"] = true, ["end"] = true, ["false"] = true, ["for"] = true, ["function"] = true, ["goto"] = true, ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, ["return"] = true, ["then"] = true, ["true"] = true, ["until"] = true, ["while"] = true} local function lua_keyword_3f(str) - local function _162_() - local _161_0 = root.options - if (nil ~= _161_0) then - _161_0 = _161_0.keywords + local function _167_() + local _166_0 = root.options + if (nil ~= _166_0) then + _166_0 = _166_0.keywords end - if (nil ~= _161_0) then - _161_0 = _161_0[str] + if (nil ~= _166_0) then + _166_0 = _166_0[str] end - return _161_0 + return _166_0 end - return (lua_keywords[str] or _162_()) + return (lua_keywords[str] or _167_()) end local function valid_lua_identifier_3f(str) return (str:match("^[%a_][%w_]*$") and not lua_keyword_3f(str)) @@ -5707,29 +5755,29 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end end local function warn(msg, _3fast, _3ffilename, _3fline) - local _167_0 = nil + local _172_0 = nil do - local _168_0 = root.options - if (nil ~= _168_0) then - _168_0 = _168_0.warn + local _173_0 = root.options + if (nil ~= _173_0) then + _173_0 = _173_0.warn end - _167_0 = _168_0 + _172_0 = _173_0 end - if (nil ~= _167_0) then - local opt_warn = _167_0 + if (nil ~= _172_0) then + local opt_warn = _172_0 return opt_warn(msg, _3fast, _3ffilename, _3fline) else - local _ = _167_0 + local _ = _172_0 if (_G.io and _G.io.stderr) then local loc = nil do - local _170_0 = ast_source(_3fast) - if ((_G.type(_170_0) == "table") and (nil ~= _170_0.filename) and (nil ~= _170_0.line)) then - local filename = _170_0.filename - local line = _170_0.line + local _175_0 = ast_source(_3fast) + if ((_G.type(_175_0) == "table") and (nil ~= _175_0.filename) and (nil ~= _175_0.line)) then + local filename = _175_0.filename + local line = _175_0.line loc = (filename .. ":" .. line .. ": ") else - local _0 = _170_0 + local _0 = _175_0 if (_3ffilename and _3fline) then loc = (_3ffilename .. ":" .. _3fline .. ": ") else @@ -5742,11 +5790,11 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end end local warned = {} - local function check_plugin_version(_175_0) - local _176_ = _175_0 - local plugin = _176_ - local name = _176_["name"] - local versions = _176_["versions"] + local function check_plugin_version(_180_0) + local _181_ = _180_0 + local plugin = _181_ + local name = _181_["name"] + local versions = _181_["versions"] if (not member_3f(version:gsub("-dev", ""), (versions or {})) and not (string_3f(versions) and version:find(versions)) and not warned[plugin]) then warned[plugin] = true return warn(string.format("plugin %s does not support Fennel version %s", (name or "unknown"), version)) @@ -5754,29 +5802,29 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local function hook_opts(event, _3foptions, ...) local plugins = nil - local function _179_(...) - local _178_0 = _3foptions - if (nil ~= _178_0) then - _178_0 = _178_0.plugins + local function _184_(...) + local _183_0 = _3foptions + if (nil ~= _183_0) then + _183_0 = _183_0.plugins end - return _178_0 + return _183_0 end - local function _182_(...) - local _181_0 = root.options - if (nil ~= _181_0) then - _181_0 = _181_0.plugins + local function _187_(...) + local _186_0 = root.options + if (nil ~= _186_0) then + _186_0 = _186_0.plugins end - return _181_0 + return _186_0 end - plugins = (_179_(...) or _182_(...)) + plugins = (_184_(...) or _187_(...)) if plugins then local result = nil for _, plugin in ipairs(plugins) do if (nil ~= result) then break end check_plugin_version(plugin) - local _184_0 = plugin[event] - if (nil ~= _184_0) then - local f = _184_0 + local _189_0 = plugin[event] + if (nil ~= _189_0) then + local f = _189_0 result = f(...) else result = nil @@ -5788,7 +5836,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. local function hook(event, ...) return hook_opts(event, root.options, ...) end - return {["ast-source"] = ast_source, ["call-of?"] = call_of_3f, ["comment?"] = comment_3f, ["debug-on?"] = debug_on_3f, ["every?"] = every_3f, ["expr?"] = expr_3f, ["fennel-module"] = nil, ["get-in"] = get_in, ["hook-opts"] = hook_opts, ["idempotent-expr?"] = idempotent_expr_3f, ["kv-table?"] = kv_table_3f, ["list?"] = list_3f, ["lua-keyword?"] = lua_keyword_3f, ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";"), ["member?"] = member_3f, ["multi-sym?"] = multi_sym_3f, ["propagate-options"] = propagate_options, ["quoted?"] = quoted_3f, ["runtime-version"] = runtime_version, ["sequence?"] = sequence_3f, ["string?"] = string_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["varg?"] = varg_3f, ["walk-tree"] = walk_tree, allpairs = allpairs, comment = comment_2a, copy = copy, expr = expr, hook = hook, len = len, list = list, maxn = maxn, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), root = root, sequence = sequence, stablepairs = stablepairs, sym = sym, varg = varg, version = version, warn = warn} + return {["ast-source"] = ast_source, ["call-of?"] = call_of_3f, ["comment?"] = comment_3f, ["debug-on?"] = debug_on_3f, ["every?"] = every_3f, ["expr?"] = expr_3f, ["fennel-module"] = nil, ["get-in"] = get_in, ["hook-opts"] = hook_opts, ["idempotent-expr?"] = idempotent_expr_3f, ["kv-table?"] = kv_table_3f, ["list?"] = list_3f, ["lua-keyword?"] = lua_keyword_3f, ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";"), ["member?"] = member_3f, ["multi-sym?"] = multi_sym_3f, ["propagate-options"] = propagate_options, ["quoted?"] = quoted_3f, ["runtime-version"] = runtime_version, ["sequence?"] = sequence_3f, ["string?"] = string_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["varg?"] = varg_3f, ["walk-tree"] = walk_tree, allpairs = allpairs, comment = comment_2a, copy = copy, expr = expr, hook = hook, len = len, list = list, maxn = maxn, pack = pack, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), root = root, sequence = sequence, stablepairs = stablepairs, sym = sym, unpack = unpack, varg = varg, version = version, warn = warn} end utils = require("fennel.utils") local parser = require("fennel.parser") @@ -5825,14 +5873,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 _841_(...) + local function _858_(...) if opts.filename then return ("@" .. opts.filename) else return str end end - loader = specials["load-code"](lua_source, env, _841_(...)) + loader = specials["load-code"](lua_source, env, _858_(...)) opts.filename = nil return loader(...) end @@ -5858,10 +5906,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 _842_0 = type(v) - if (_842_0 == "function") then + local _859_0 = type(v) + if (_859_0 == "function") then out[k] = {["function?"] = true, ["global?"] = true} - elseif (_842_0 == "table") then + elseif (_859_0 == "table") then if not k:find("^_") then for k2, v2 in pairs(v) do if ("function" == type(v2)) then @@ -5880,841 +5928,840 @@ mod.install = function(_3fopts) return mod end utils["fennel-module"] = mod +local function load_macros(src, env) + local chunk = assert(specials["load-code"](src, env, "src/fennel/macros.fnl")) + for k, v in pairs(chunk()) do + compiler.scopes.global.macros[k] = v + end + return nil +end do - local module_name = "fennel.macros" - local _ = nil - local function _846_() - return mod + local env = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) + env.utils = utils + env["get-function-metadata"] = specials["get-function-metadata"] + load_macros([===[local function copy(t) + local out = {} + for _, v in ipairs(t) do + table.insert(out, v) + end + return setmetatable(out, getmetatable(t)) end - package.preload[module_name] = _846_ - _ = nil - local env = nil - do - local _847_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) - _847_0["utils"] = utils - _847_0["fennel"] = mod - _847_0["get-function-metadata"] = specials["get-function-metadata"] - env = _847_0 + utils['fennel-module'].metadata:setall(copy, "fnl/arglist", {"t"}) + local function __3e_2a(val, ...) + local x = val + for _, e in ipairs({...}) do + local elt = nil + if _G["list?"](e) then + elt = copy(e) + else + elt = list(e) + end + table.insert(elt, 2, x) + x = elt + end + return x end - 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] - (let [out []] - (each [_ v (ipairs t)] (table.insert out v)) - (setmetatable out (getmetatable t)))) - - (fn ->* [val ...] - "Thread-first macro. - Take the first value and splice it into the second form as its first argument. - The value of the second form is spliced into the first arg of the third, etc." - (var x val) - (each [_ e (ipairs [...])] - (let [elt (if (list? e) (copy e) (list e))] - (table.insert elt 2 x) - (set x elt))) - x) - - (fn ->>* [val ...] - "Thread-last macro. - Same as ->, except splices the value into the last position of each form - rather than the first." - (var x val) - (each [_ e (ipairs [...])] - (let [elt (if (list? e) (copy e) (list e))] - (table.insert elt x) - (set x elt))) - x) - - (fn -?>* [val ?e ...] - "Nil-safe thread-first macro. - Same as -> except will short-circuit with nil when it encounters a nil value." - (if (= nil ?e) - val - (not (utils.idempotent-expr? val)) - ;; try again, but with an eval-safe val - `(let [tmp# ,val] - (-?> tmp# ,?e ,...)) - (let [call (if (list? ?e) (copy ?e) (list ?e))] - (table.insert call 2 val) - `(if (not= nil ,val) - ,(-?>* call ...))))) - - (fn -?>>* [val ?e ...] - "Nil-safe thread-last macro. - Same as ->> except will short-circuit with nil when it encounters a nil value." - (if (= nil ?e) - val - (not (utils.idempotent-expr? val)) - ;; try again, but with an eval-safe val - `(let [tmp# ,val] - (-?>> tmp# ,?e ,...)) - (let [call (if (list? ?e) (copy ?e) (list ?e))] - (table.insert call val) - `(if (not= ,val nil) - ,(-?>>* call ...))))) - - (fn ?dot [tbl ...] - "Nil-safe table look up. - Same as . (dot), except will short-circuit with nil when it encounters - a nil value in any of subsequent keys." - (let [head (gensym :t) - lookups `(do - (var ,head ,tbl) - ,head)] - (each [i k (ipairs [...])] - ;; Kinda gnarly to reassign in place like this, but it emits the best lua. - ;; With this impl, it emits a flat, concise, and readable set of ifs - (table.insert lookups (+ i 2) - `(if (not= nil ,head) (set ,head (. ,head ,k))))) - lookups)) - - (fn doto* [val ...] - "Evaluate val and splice it into the first argument of subsequent forms." - (assert (not= val nil) "missing subject") - (if (not (utils.idempotent-expr? val)) - `(let [tmp# ,val] - (doto tmp# ,...)) - (let [form `(do)] - (each [_ elt (ipairs [...])] - (let [elt (if (list? elt) (copy elt) (list elt))] - (table.insert elt 2 val) - (table.insert form elt))) - (table.insert form val) - form))) - - (fn when* [condition body1 ...] - "Evaluate body for side-effects only when condition is truthy." - (assert body1 "expected body") - `(if ,condition - (do - ,body1 - ,...))) - - (fn with-open* [closable-bindings ...] - "Like `let`, but invokes (v:close) on each binding after evaluating the body. - The body is evaluated inside `xpcall` so that bound values will be closed upon - encountering an error before propagating it." - (let [bodyfn `(fn [] - ,...) - closer `(fn close-handlers# [ok# ...] - (if ok# ... (error ... 0))) - traceback `(. (or (. package.loaded ,(fennel-module-name)) _G.debug {}) - :traceback)] - (for [i 1 (length closable-bindings) 2] - (assert (sym? (. closable-bindings i)) - "with-open only allows symbols in bindings") - (table.insert closer 4 `(: ,(. closable-bindings i) :close))) - `(let ,closable-bindings - ,closer - (close-handlers# (_G.xpcall ,bodyfn ,traceback))))) - - (fn extract-into [iter-tbl] - (var (into iter-out found?) (values [] (copy iter-tbl))) - (for [i (length iter-tbl) 2 -1] - (let [item (. iter-tbl i)] - (if (or (sym? item "&into") (= :into item)) - (do - (assert (not found?) "expected only one &into clause") - (set found? true) - (set into (. iter-tbl (+ i 1))) - (table.remove iter-out i) - (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 found?)) - - (fn collect* [iter-tbl key-expr value-expr ...] - "Return a table made by running an iterator and evaluating an expression that - returns key-value pairs to be inserted sequentially into the table. This can - be thought of as a table comprehension. The body should provide two expressions - (used as key and value) or nil, which causes it to be omitted. - - For example, - (collect [k v (pairs {:apple \"red\" :orange \"orange\"})] - (values v k)) - returns - {:red \"apple\" :orange \"orange\"} - - Supports an &into clause after the iterator to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl))) - "expected iterator binding table") - (assert (not= nil key-expr) "expected key and value expression") - (assert (= nil ...) - "expected 1 or 2 body expressions; wrap multiple expressions with do") - (assert (or value-expr (list? key-expr)) "need key and value") - (let [kv-expr (if (= nil value-expr) key-expr `(values ,key-expr ,value-expr)) - (into iter) (extract-into iter-tbl)] - `(let [tbl# ,into] - (each ,iter - (let [(k# v#) ,kv-expr] - (if (and (not= k# nil) (not= v# nil)) - (tset tbl# k# v#)))) - tbl#))) - - (fn seq-collect [how iter-tbl value-expr ...] - "Common part between icollect and fcollect for producing sequential tables. - - Iteration code only differs in using the for or each keyword, the rest - of the generated code is identical." - (assert (not= nil value-expr) "expected table value expression") - (assert (= nil ...) - "expected exactly one body expression. Wrap multiple expressions in do") - (let [(into iter has-into?) (extract-into iter-tbl)] - (if has-into? - `(let [tbl# ,into] - (,how ,iter (let [val# ,value-expr] - (table.insert tbl# val#))) - 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 - expression that returns values to be inserted sequentially into the table. - This can be thought of as a table comprehension. If the body evaluates to nil - that element is omitted. - - For example, - (icollect [_ v (ipairs [1 2 3 4 5])] - (when (not= v 3) - (* v v))) - returns - [1 4 16 25] - - Supports an &into clause after the iterator to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl))) - "expected iterator binding table") - (seq-collect 'each iter-tbl value-expr ...)) - - (fn fcollect* [iter-tbl value-expr ...] - "Return a sequential table made by advancing a range as specified by - for, and evaluating an expression that returns values to be inserted - sequentially into the table. This can be thought of as a range - comprehension. If the body evaluates to nil that element is omitted. - - For example, - (fcollect [i 1 10 2] - (when (not= i 3) - (* i i))) - returns - [1 25 49 81] - - Supports an &into clause after the range to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (< 2 (length iter-tbl))) - "expected range binding table") - (seq-collect 'for iter-tbl value-expr ...)) - - (fn accumulate-impl [for? iter-tbl body ...] - (assert (and (sequence? iter-tbl) (<= 4 (length iter-tbl))) - "expected initial value and iterator binding table") - (assert (not= nil body) "expected body expression") - (assert (= nil ...) - "expected exactly one body expression. Wrap multiple expressions with do") - (let [[accum-var accum-init] iter-tbl - iter (sym (if for? "for" "each"))] ; accumulate or faccumulate? - `(do - (var ,accum-var ,accum-init) - (,iter ,[(unpack iter-tbl 3)] - (set ,accum-var ,body)) - ,(if (list? accum-var) - (list (sym :values) (unpack accum-var)) - accum-var)))) - - (fn accumulate* [iter-tbl body ...] - "Accumulation macro. - - It takes a binding table and an expression as its arguments. In the binding - table, the first form starts out bound to the second value, which is an initial - accumulator. The rest are an iterator binding table in the format `each` takes. - - It runs through the iterator in each step of which the given expression is - evaluated, and the accumulator is set to the value of the expression. It - eventually returns the final value of the accumulator. - - For example, - (accumulate [total 0 - _ n (pairs {:apple 2 :orange 3})] - (+ total n)) - returns 5" - (accumulate-impl false iter-tbl body ...)) - - (fn faccumulate* [iter-tbl body ...] - "Identical to accumulate, but after the accumulator the binding table is the - same as `for` instead of `each`. Like collect to fcollect, will iterate over a - numerical range like `for` rather than an iterator." - (accumulate-impl true iter-tbl body ...)) - - (fn partial* [f ...] - "Return a function with all arguments partially applied to f." - (assert f "expected a function to partially apply") - (let [bindings [] - args []] - (each [_ arg (ipairs [...])] - (if (utils.idempotent-expr? arg) - (table.insert args arg) - (let [name (gensym)] - (table.insert bindings name) - (table.insert bindings arg) - (table.insert args name)))) - (let [body (list f (unpack args))] - (table.insert body _VARARG) - ;; only use the extra let if we need double-eval protection - (if (= nil (. bindings 1)) - `(fn [,_VARARG] ,body) - `(let ,bindings - (fn [,_VARARG] ,body)))))) - - (fn pick-args* [n f] - "Create a function of arity n that applies its arguments to f. Deprecated." - (if (and _G.io _G.io.stderr) - (_G.io.stderr:write - "-- WARNING: pick-args is deprecated and will be removed in the future.\n")) - (let [bindings []] - (for [i 1 n] (tset bindings i (gensym))) - `(fn ,bindings (,f ,(unpack bindings))))) - - (fn lambda* [...] - "Function literal with nil-checked arguments. - Like `fn`, but will throw an exception if a declared argument is passed in as - nil, unless that argument's name begins with a question mark." - (let [args [...] - args-len (length args) - has-internal-name? (sym? (. args 1)) - arglist (if has-internal-name? (. args 2) (. args 1)) - metadata-position (if has-internal-name? 3 2) - (_ check-position) (get-function-metadata [:lambda ...] arglist - metadata-position) - empty-body? (< args-len check-position)] - (fn check! [a] - (if (table? a) - (each [_ a (pairs a)] (check! a)) - (let [as (tostring a)] - (and (not (as:find "^?")) (not= as "&") (not (as:find "^_")) - (not= as "...") (not= as "&as"))) - (table.insert args check-position - `(_G.assert (not= nil ,a) - ,(: "Missing argument %s on %s:%s" :format - (tostring a) - (or a.filename :unknown) - (or a.line "?")))))) - - (assert (= :table (type arglist)) "expected arg list") - (each [_ a (ipairs arglist)] (check! a)) - (if empty-body? (table.insert args (sym :nil))) - `(fn ,(unpack args)))) - - (fn macro* [name ...] - "Define a single macro." - (assert (sym? name) "expected symbol for macro name") - (local args [...]) - `(macros {,(tostring name) (fn ,(unpack args))})) - - (fn macrodebug* [form return?] - "Print the resulting form after performing macroexpansion. - With a second argument, returns expanded form as a string instead of printing." - (let [handle (if return? `do `print)] - ;; TODO: Provide a helpful compiler error in the unlikely edge case of an - ;; infinite AST instead of the current "silently expand until max depth" - `(,handle ,(view (macroexpand form _SCOPE) {:detect-cycles? false})))) - - (fn import-macros* [binding1 module-name1 ...] - "Bind a table of macros from each macro module according to a binding form. - Each binding form can be either a symbol or a k/v destructuring table. - Example: - (import-macros mymacros :my-macros ; bind to symbol - {:macro1 alias : macro2} :proj.macros) ; import by name" - (assert (and binding1 module-name1 (= 0 (% (select "#" ...) 2))) - "expected even number of binding/modulename pairs") - (for [i 1 (select "#" binding1 module-name1 ...) 2] - ;; delegate the actual loading of the macros to the require-macros - ;; special which already knows how to set up the compiler env and stuff. - ;; this is weird because require-macros is deprecated but it works. - (let [(binding modname) (select i binding1 module-name1 ...) - scope (get-scope) - ;; if the module-name is an expression (and not just a string) we - ;; patch our expression to have the correct source filename so - ;; require-macros can pass it down when resolving the module-name. - expr `(import-macros ,modname) - filename (if (list? modname) (. modname 1 :filename) :unknown) - _ (tset expr :filename filename) - macros* (_SPECIALS.require-macros expr scope {} binding)] - (if (sym? binding) - ;; bind whole table of macros to table bound to symbol - (tset scope.macros (. binding 1) macros*) - ;; 1-level table destructuring for importing individual macros - (table? binding) - (each [macro-name [import-key] (pairs binding)] - (assert (= :function (type (. macros* macro-name))) - (.. "macro " macro-name " not found in module " - (tostring modname))) - (tset scope.macros import-key (. macros* macro-name)))))) - nil) - - (fn assert-repl* [condition ...] - "Enter into a debug REPL and print the message when condition is false/nil. - Works as a drop-in replacement for Lua's `assert`. - REPL `,return` command returns values to assert in place to continue execution." - {:fnl/arglist [condition ?message ...]} - (fn add-locals [{: symmeta : parent} locals] - (each [name (pairs symmeta)] - (tset locals name (sym name))) - (if parent (add-locals parent locals) locals)) - `(let [unpack# (or table.unpack _G.unpack) - pack# (or table.pack #(doto [$...] (tset :n (select :# $...)))) - ;; need to pack/unpack input args to account for (assert (foo)), - ;; because assert returns *all* arguments upon success - vals# (pack# ,condition ,...) - condition# (. vals# 1) - message# (or (. vals# 2) "assertion failed, entering repl.")] - (if (not condition#) - (let [opts# {:assert-repl? true} - fennel# (require ,(fennel-module-name)) - 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#))) - (values (unpack# vals# 1 vals#.n))))) - - {:-> ->* - :->> ->>* - :-?> -?>* - :-?>> -?>>* - :?. ?dot - :doto doto* - :when when* - :with-open with-open* - :collect collect* - :icollect icollect* - :fcollect fcollect* - :accumulate accumulate* - :faccumulate faccumulate* - :partial partial* - :lambda lambda* - :λ lambda* - :pick-args pick-args* - :macro macro* - :macrodebug macrodebug* - :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 + utils['fennel-module'].metadata:setall(__3e_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Thread-first macro.\nTake the first value and splice it into the second form as its first argument.\nThe value of the second form is spliced into the first arg of the third, etc.") + local function __3e_3e_2a(val, ...) + local x = val + for _, e in ipairs({...}) do + local elt = nil + if _G["list?"](e) then + elt = copy(e) + else + elt = list(e) + end + table.insert(elt, x) + x = elt + end + return x end - _0 = nil - 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. - - (fn copy [t] (collect [k v (pairs t)] k v)) - - (fn double-eval-safe? [x type] - (or (= :number type) (= :string type) (= :boolean type) - (and (sym? x) (not (multi-sym? x))))) - - (fn with [opts k] - (doto (copy opts) (tset k true))) - - (fn without [opts k] - (doto (copy opts) (tset k nil))) - - (fn case-values [vals pattern unifications case-pattern opts] - (let [condition `(and) - bindings []] - (each [i pat (ipairs pattern)] - (let [(subcondition subbindings) (case-pattern [(. vals i)] pat - unifications (without opts :multival?))] - (table.insert condition subcondition) - (icollect [_ b (ipairs subbindings) &into bindings] b))) - (values condition bindings))) - - (fn case-table [val pattern unifications case-pattern opts ?top] - (let [condition (if (= :table ?top) `(and) `(and (= (_G.type ,val) :table))) - bindings []] - (each [k pat (pairs pattern)] - (if (sym? pat :&) - (let [rest-pat (. pattern (+ k 1)) - rest-val `(select ,k ((or table.unpack _G.unpack) ,val)) - subcondition (case-table `(pick-values 1 ,rest-val) - rest-pat unifications case-pattern - (without opts :multival?))] - (if (not (sym? rest-pat)) - (table.insert condition subcondition)) - (assert (= nil (. pattern (+ k 2))) - "expected & rest argument before last parameter") - (table.insert bindings rest-pat) - (table.insert bindings [rest-val])) - (sym? k :&as) - (do - (table.insert bindings pat) - (table.insert bindings val)) - (and (= :number (type k)) (sym? pat :&as)) - (do - (assert (= nil (. pattern (+ k 2))) - "expected &as argument before last parameter") - (table.insert bindings (. pattern (+ k 1))) - (table.insert bindings val)) - ;; don't process the pattern right after &/&as; already got it - (or (not= :number (type k)) (and (not (sym? (. pattern (- k 1)) :&as)) - (not (sym? (. pattern (- k 1)) :&)))) - (let [subval `(. ,val ,k) - (subcondition subbindings) (case-pattern [subval] pat - unifications - (without opts :multival?))] - (table.insert condition subcondition) - (icollect [_ b (ipairs subbindings) &into bindings] b)))) - (values condition bindings))) - - (fn case-guard [vals condition guards unifications case-pattern opts] - (if (. guards 1) - (let [(pcondition bindings) (case-pattern vals condition unifications opts) - condition `(and ,(unpack guards))] - (values `(and ,pcondition - (let ,bindings - ,condition)) bindings)) - (case-pattern vals condition unifications opts))) - - (fn symbols-in-pattern [pattern] - "gives the set of symbols inside a pattern" - (if (list? pattern) - (if (or (sym? (. pattern 1) :where) - (sym? (. pattern 1) :=)) - (symbols-in-pattern (. pattern 2)) - (sym? (. pattern 2) :?) - (symbols-in-pattern (. pattern 1)) - (let [result {}] - (each [_ child-pattern (ipairs pattern)] - (collect [name symbol (pairs (symbols-in-pattern child-pattern)) &into result] - name symbol)) - result)) - (sym? pattern) - (if (and (not (sym? pattern :or)) - (not (sym? pattern :nil))) - {(tostring pattern) pattern} - {}) - (= (type pattern) :table) - (let [result {}] - (each [key-pattern value-pattern (pairs pattern)] - (collect [name symbol (pairs (symbols-in-pattern key-pattern)) &into result] - name symbol) - (collect [name symbol (pairs (symbols-in-pattern value-pattern)) &into result] - name symbol)) - result) - {})) - - (fn symbols-in-every-pattern [pattern-list infer-unification?] - "gives a list of symbols that are present in every pattern in the list" - (let [?symbols (accumulate [?symbols nil - _ pattern (ipairs pattern-list)] - (let [in-pattern (symbols-in-pattern pattern)] - (if ?symbols - (do - (each [name (pairs ?symbols)] - (when (not (. in-pattern name)) - (tset ?symbols name nil))) - ?symbols) - in-pattern)))] - (icollect [_ symbol (pairs (or ?symbols {}))] - (if (not (and infer-unification? - (in-scope? symbol))) - symbol)))) - - (fn case-or [vals pattern guards unifications case-pattern opts] - (let [pattern [(unpack pattern 2)] - bindings (symbols-in-every-pattern pattern opts.infer-unification?)] - (if (= nil (. bindings 1)) - ;; no bindings special case generates simple code - (let [condition (icollect [_ subpattern (ipairs pattern) &into `(or)] - (case-pattern vals subpattern unifications opts))] - (values (if (. guards 1) - `(and ,condition ,(unpack guards)) - condition) - [])) - ;; case with bindings is handled specially, and returns three values instead of two - (let [matched? (gensym :matched?) - bindings-mangled (icollect [_ binding (ipairs bindings)] - (gensym (tostring binding))) - pre-bindings `(if)] - (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 - (values true ,(unpack bindings)))))) - (values matched? - [`(,(unpack bindings)) `(values ,(unpack bindings-mangled))] - [`(,matched? ,(unpack bindings-mangled)) pre-bindings]))))) - - (fn case-pattern [vals pattern unifications opts ?top] - "Take the AST of values and a single pattern and returns a condition - to determine if it matches as well as a list of bindings to - introduce for the duration of the body if it does match." - - ;; This function returns the following values (multival): - ;; a "condition", which is an expression that determines whether the - ;; pattern should match, - ;; a "bindings", which bind all of the symbols used in a pattern - ;; an optional "pre-bindings", which is a list of bindings that happen - ;; before the condition and bindings are evaluated. These should only - ;; come from a (case-or). In this case there should be no recursion: - ;; the call stack should be case-condition > case-pattern > case-or - ;; - ;; Here are the expected flags in the opts table: - ;; :infer-unification? boolean - if the pattern should guess when to unify (ie, match -> true, case -> false) - ;; :multival? boolean - if the pattern can contain multivals (in order to disallow patterns like [(1 2)]) - ;; :in-where? boolean - if the pattern is surrounded by (where) (where opts into more pattern features) - ;; :legacy-guard-allowed? boolean - if the pattern should allow `(a ? b) patterns - - ;; we have to assume we're matching against multiple values here until we - ;; know we're either in a multi-valued clause (in which case we know the # - ;; of vals) or we're not, in which case we only care about the first one. - (let [[val] vals] - (if (and (sym? pattern) - (or (sym? pattern :nil) - (and opts.infer-unification? - (in-scope? pattern) - (not (sym? pattern :_))) - (and opts.infer-unification? - (multi-sym? pattern) - (in-scope? (. (multi-sym? pattern) 1))))) - (values `(= ,val ,pattern) []) - ;; unify a local we've seen already - (and (sym? pattern) (. unifications (tostring pattern))) - (values `(= ,(. unifications (tostring pattern)) ,val) []) - ;; bind a fresh local - (sym? pattern) - (let [wildcard? (: (tostring pattern) :find "^_")] - (if (not wildcard?) (tset unifications (tostring pattern) val)) - (values (if (or wildcard? (string.find (tostring pattern) "^?")) true - `(not= ,(sym :nil) ,val)) [pattern val])) - ;; opt-in unify with (=) - (and (list? pattern) - (sym? (. pattern 1) :=) - (sym? (. pattern 2))) - (let [bind (. pattern 2)] - (assert-compile (= 2 (length pattern)) "(=) should take only one argument" pattern) - (assert-compile (not opts.infer-unification?) "(=) cannot be used inside of match" pattern) - (assert-compile opts.in-where? "(=) must be used in (where) patterns" pattern) - (assert-compile (and (sym? bind) (not (sym? bind :nil)) "= has to bind to a symbol" bind)) - (values `(= ,val ,bind) [])) - ;; where-or clause - (and (list? pattern) (sym? (. pattern 1) :where) (list? (. pattern 2)) (sym? (. pattern 2 1) :or)) - (do - (assert-compile ?top "can't nest (where) pattern" pattern) - (case-or vals (. pattern 2) [(unpack pattern 3)] unifications case-pattern (with opts :in-where?))) - ;; where clause - (and (list? pattern) (sym? (. pattern 1) :where)) - (do - (assert-compile ?top "can't nest (where) pattern" pattern) - (case-guard vals (. pattern 2) [(unpack pattern 3)] unifications case-pattern (with opts :in-where?))) - ;; or clause (not allowed on its own) - (and (list? pattern) (sym? (. pattern 1) :or)) - (do - (assert-compile ?top "can't nest (or) pattern" pattern) - ;; This assertion can be removed to make patterns more permissive - (assert-compile false "(or) must be used in (where) patterns" pattern) - (case-or vals pattern [] unifications case-pattern opts)) - ;; guard clause - (and (list? pattern) (sym? (. pattern 2) :?)) - (do - (assert-compile opts.legacy-guard-allowed? "legacy guard clause not supported in case" pattern) - (case-guard vals (. pattern 1) [(unpack pattern 3)] unifications case-pattern opts)) - ;; multi-valued patterns (represented as lists) - (list? pattern) - (do - (assert-compile opts.multival? "can't nest multi-value destructuring" pattern) - (case-values vals pattern unifications case-pattern opts)) - ;; table patterns - (= (type pattern) :table) - (case-table val pattern unifications case-pattern opts ?top) - ;; literal value - (values `(= ,val ,pattern) [])))) - - (fn add-pre-bindings [out pre-bindings] - "Decide when to switch from the current `if` AST to a new one" - (if pre-bindings - ;; `out` no longer needs to grow. - ;; Instead, a new tail `if` AST is introduced, which is where the rest of - ;; the clauses will get appended. This way, all future clauses have the - ;; pre-bindings in scope. - (let [tail `(if)] - (table.insert out true) - (table.insert out `(let ,pre-bindings ,tail)) - tail) - ;; otherwise, keep growing the current `if` AST. - out)) - - (fn case-condition [vals clauses match? top-table?] - "Construct the actual `if` AST for the given match values and clauses." - ;; root is the original `if` AST. - ;; out is the `if` AST that is currently being grown. - (let [root `(if)] - (faccumulate [out root - i 1 (length clauses) 2] - (let [pattern (. clauses i) - body (. clauses (+ i 1)) - (condition bindings pre-bindings) (case-pattern vals pattern {} - {:multival? true - :infer-unification? match? - :legacy-guard-allowed? match?} - (if top-table? :table true)) - out (add-pre-bindings out pre-bindings)] - ;; grow the `if` AST by one extra condition - (table.insert out condition) - (table.insert out `(let ,bindings ,body)) - out)) - root)) - - (fn count-case-multival [pattern] - "Identify the amount of multival values that a pattern requires." - (if (and (list? pattern) (sym? (. pattern 2) :?)) - (count-case-multival (. pattern 1)) - (and (list? pattern) (sym? (. pattern 1) :where)) - (count-case-multival (. pattern 2)) - (and (list? pattern) (sym? (. pattern 1) :or)) - (accumulate [longest 0 - _ child-pattern (ipairs pattern)] - (math.max longest (count-case-multival child-pattern))) - (list? pattern) - (length pattern) - 1)) - - (fn case-count-syms [clauses] - "Find the length of the largest multi-valued clause" - (let [patterns (fcollect [i 1 (length clauses) 2] - (. clauses i))] - (accumulate [longest 0 - _ pattern (ipairs patterns)] - (math.max longest (count-case-multival pattern))))) - - (fn maybe-optimize-table [val clauses] - (if (faccumulate [all (sequence? val) i 1 (length clauses) 2 &until (not all)] - (and (sequence? (. clauses i)) - (accumulate [all2 (next (. clauses i)) - _ d (ipairs (. clauses i)) &until (not all2)] - (and all2 (or (not (sym? d)) (not (: (tostring d) :find "^&"))))))) - (values `(values ,(unpack val)) - (fcollect [i 1 (length clauses)] - (if (= 1 (% i 2)) - (list (unpack (. clauses i))) - (. clauses i)))) - (values val clauses))) - - (fn case-impl [match? init-val ...] - "The shared implementation of case and match." - (assert (not= init-val nil) "missing subject") - (assert (= 0 (math.fmod (select :# ...) 2)) - "expected even number of pattern/body pairs") - (assert (not= 0 (select :# ...)) - "expected at least one pattern/body pair") - (let [(val clauses) (maybe-optimize-table init-val [...]) - vals-count (case-count-syms clauses) - skips-multiple-eval-protection? (and (= vals-count 1) (double-eval-safe? val))] - (if skips-multiple-eval-protection? - (case-condition (list val) clauses match? (table? init-val)) - ;; protect against multiple evaluation of the value, bind against as - ;; many values as we ever match against in the clauses. - (let [vals (fcollect [_ 1 vals-count &into (list)] (gensym))] - (list `let [vals val] (case-condition vals clauses match? (table? init-val))))))) - - (fn case* [val ...] - "Perform pattern matching on val. See reference for details. - - Syntax: - - (case data-expression - pattern body - (where pattern guards*) body - (where (or pattern patterns*) guards*) body)" - (case-impl false val ...)) - - (fn match* [val ...] - "Perform pattern matching on val, automatically unifying on variables in - local scope. See reference for details. - - Syntax: - - (match data-expression - pattern body - (where pattern guards*) body - (where (or pattern patterns*) guards*) body)" - (case-impl true val ...)) - - (fn case-try-step [how expr else pattern body ...] - (if (= nil pattern body) - expr - ;; unlike regular match, we can't know how many values the value - ;; might evaluate to, so we have to capture them all in ... via IIFE - ;; to avoid double-evaluation. - `((fn [...] - (,how ... - ,pattern ,(case-try-step how body else ...) - ,(unpack else))) - ,expr))) - - (fn case-try-impl [how expr pattern body ...] - (let [clauses [pattern body ...] - last (. clauses (length clauses)) - catch (if (sym? (and (= :table (type last)) (. last 1)) :catch) - (let [[_ & e] (table.remove clauses)] e) ; remove `catch sym - [`_# `...])] - (assert (= 0 (math.fmod (length clauses) 2)) - "expected every pattern to have a body") - (assert (= 0 (math.fmod (length catch) 2)) - "expected every catch pattern to have a body") - (case-try-step how expr catch (unpack clauses)))) - - (fn case-try* [expr pattern body ...] - "Perform chained pattern matching for a sequence of steps which might fail. - - The values from the initial expression are matched against the first pattern. - If they match, the first body is evaluated and its values are matched against - the second pattern, etc. - - If there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch - from the steps will be tried against these patterns in sequence as a fallback - just like a normal match. If there is no catch, the mismatched values will be - returned as the value of the entire expression." - (case-try-impl `case expr pattern body ...)) - - (fn match-try* [expr pattern body ...] - "Perform chained pattern matching for a sequence of steps which might fail. - - The values from the initial expression are matched against the first pattern. - If they match, the first body is evaluated and its values are matched against - the second pattern, etc. - - If there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch - from the steps will be tried against these patterns in sequence as a fallback - just like a normal match. If there is no catch, the mismatched values will be - returned as the value of the entire expression." - (case-try-impl `match expr pattern body ...)) - - {:case case* - :case-try case-try* - :match match* - :match-try match-try*} - ]===], {allowedGlobals = false, env = env, filename = "src/fennel/match.fnl", moduleName = module_name, scope = compiler.scopes.compiler, useMetadata = true}) - for k, v in pairs(match_macros) do - compiler.scopes.global.macros[k] = v + utils['fennel-module'].metadata:setall(__3e_3e_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Thread-last macro.\nSame as ->, except splices the value into the last position of each form\nrather than the first.") + local function __3f_3e_2a(val, _3fe, ...) + if (nil == _3fe) then + return val + elseif not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=40, bytestart=1174, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=40}), setmetatable({sym('tmp_3_', nil, {filename="src/fennel/macros.fnl", line=40}), val}, {filename="src/fennel/macros.fnl", line=40}), setmetatable({filename="src/fennel/macros.fnl", line=41, bytestart=1199, sym('-?>', nil, {quoted=true, filename="src/fennel/macros.fnl", line=41}), sym('tmp_3_', nil, {filename="src/fennel/macros.fnl", line=41}), _3fe, ...}, getmetatable(list()))}, getmetatable(list())) + else + local call = nil + if _G["list?"](_3fe) then + call = copy(_3fe) + else + call = list(_3fe) + end + table.insert(call, 2, val) + return setmetatable({filename="src/fennel/macros.fnl", line=44, bytestart=1317, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), setmetatable({filename="src/fennel/macros.fnl", line=44, bytestart=1321, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), val}, getmetatable(list())), __3f_3e_2a(call, ...)}, getmetatable(list())) + end end - package.preload[module_name] = nil + utils['fennel-module'].metadata:setall(__3f_3e_2a, "fnl/arglist", {"val", "?e", "..."}, "fnl/docstring", "Nil-safe thread-first macro.\nSame as -> except will short-circuit with nil when it encounters a nil value.") + local function __3f_3e_3e_2a(val, _3fe, ...) + if (nil == _3fe) then + return val + elseif not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=54, bytestart=1627, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=54}), setmetatable({sym('tmp_6_', nil, {filename="src/fennel/macros.fnl", line=54}), val}, {filename="src/fennel/macros.fnl", line=54}), setmetatable({filename="src/fennel/macros.fnl", line=55, bytestart=1652, sym('-?>>', nil, {quoted=true, filename="src/fennel/macros.fnl", line=55}), sym('tmp_6_', nil, {filename="src/fennel/macros.fnl", line=55}), _3fe, ...}, getmetatable(list()))}, getmetatable(list())) + else + local call = nil + if _G["list?"](_3fe) then + call = copy(_3fe) + else + call = list(_3fe) + end + table.insert(call, val) + return setmetatable({filename="src/fennel/macros.fnl", line=58, bytestart=1769, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58}), setmetatable({filename="src/fennel/macros.fnl", line=58, bytestart=1773, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58}), val, sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58})}, getmetatable(list())), __3f_3e_3e_2a(call, ...)}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(__3f_3e_3e_2a, "fnl/arglist", {"val", "?e", "..."}, "fnl/docstring", "Nil-safe thread-last macro.\nSame as ->> except will short-circuit with nil when it encounters a nil value.") + local function _3fdot(tbl, ...) + local head = gensym("t") + local lookups = setmetatable({filename="src/fennel/macros.fnl", line=66, bytestart=2024, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=66}), setmetatable({filename="src/fennel/macros.fnl", line=67, bytestart=2047, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=67}), head, tbl}, getmetatable(list())), head}, getmetatable(list())) + for i, k in ipairs({...}) do + table.insert(lookups, (i + 2), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2335, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2339, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2356, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head, setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2367, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head, k}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))) + end + return lookups + end + utils['fennel-module'].metadata:setall(_3fdot, "fnl/arglist", {"tbl", "..."}, "fnl/docstring", "Nil-safe table look up.\nSame as . (dot), except will short-circuit with nil when it encounters\na nil value in any of subsequent keys.") + local function doto_2a(val, ...) + assert((val ~= nil), "missing subject") + if not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=80, bytestart=2585, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=80}), setmetatable({sym('tmp_9_', nil, {filename="src/fennel/macros.fnl", line=80}), val}, {filename="src/fennel/macros.fnl", line=80}), setmetatable({filename="src/fennel/macros.fnl", line=81, bytestart=2609, sym('doto', nil, {quoted=true, filename="src/fennel/macros.fnl", line=81}), sym('tmp_9_', nil, {filename="src/fennel/macros.fnl", line=81}), ...}, getmetatable(list()))}, getmetatable(list())) + else + local form = setmetatable({filename="src/fennel/macros.fnl", line=82, bytestart=2643, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=82})}, getmetatable(list())) + for _, elt in ipairs({...}) do + local elt0 = nil + if _G["list?"](elt) then + elt0 = copy(elt) + else + elt0 = list(elt) + end + table.insert(elt0, 2, val) + table.insert(form, elt0) + end + table.insert(form, val) + return form + end + end + utils['fennel-module'].metadata:setall(doto_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Evaluate val and splice it into the first argument of subsequent forms.") + local function when_2a(condition, body1, ...) + assert(body1, "expected body") + return setmetatable({filename="src/fennel/macros.fnl", line=93, bytestart=2992, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=93}), condition, setmetatable({filename="src/fennel/macros.fnl", line=94, bytestart=3014, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=94}), body1, ...}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(when_2a, "fnl/arglist", {"condition", "body1", "..."}, "fnl/docstring", "Evaluate body for side-effects only when condition is truthy.") + local function with_open_2a(closable_bindings, ...) + local bodyfn = setmetatable({filename="src/fennel/macros.fnl", line=102, bytestart=3312, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=102}), setmetatable({}, {filename="src/fennel/macros.fnl", line=102}), ...}, getmetatable(list())) + local closer = setmetatable({filename="src/fennel/macros.fnl", line=104, bytestart=3359, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=104}), sym('close-handlers_12_', nil, {filename="src/fennel/macros.fnl", line=104}), setmetatable({sym('ok_13_', nil, {filename="src/fennel/macros.fnl", line=104}), _VARARG}, {filename="src/fennel/macros.fnl", line=104}), setmetatable({filename="src/fennel/macros.fnl", line=105, bytestart=3407, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=105}), sym('ok_13_', nil, {filename="src/fennel/macros.fnl", line=105}), _VARARG, setmetatable({filename="src/fennel/macros.fnl", line=105, bytestart=3419, sym('error', nil, {quoted=true, filename="src/fennel/macros.fnl", line=105}), _VARARG, 0}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + local traceback = setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3454, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3457, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3461, sym('?.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), sym('_G', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), "package", "loaded", _G["fennel-module-name"]()}, getmetatable(list())), sym('_G.debug', nil, {quoted=true, filename="src/fennel/macros.fnl", line=107}), setmetatable({["traceback"]=setmetatable({filename=nil, line=nil, bytestart=nil, sym('hashfn', nil, {quoted=true, filename=nil, line=nil}), ""}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=107})}, getmetatable(list())), "traceback"}, getmetatable(list())) + for i = 1, #closable_bindings, 2 do + assert(_G["sym?"](closable_bindings[i]), "with-open only allows symbols in bindings") + table.insert(closer, 4, setmetatable({filename="src/fennel/macros.fnl", line=111, bytestart=3752, sym(':', nil, {quoted=true, filename="src/fennel/macros.fnl", line=111}), closable_bindings[i], "close"}, getmetatable(list()))) + end + return setmetatable({filename="src/fennel/macros.fnl", line=112, bytestart=3795, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=112}), closable_bindings, closer, setmetatable({filename="src/fennel/macros.fnl", line=114, bytestart=3841, sym('close-handlers_12_', nil, {filename="src/fennel/macros.fnl", line=114}), setmetatable({filename="src/fennel/macros.fnl", line=114, bytestart=3858, sym('_G.xpcall', nil, {quoted=true, filename="src/fennel/macros.fnl", line=114}), bodyfn, traceback}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(with_open_2a, "fnl/arglist", {"closable-bindings", "..."}, "fnl/docstring", "Like `let`, but invokes (v:close) on each binding after evaluating the body.\nThe body is evaluated inside `xpcall` so that bound values will be closed upon\nencountering an error before propagating it.") + local function extract_into(iter_tbl) + local into, iter_out, found_3f = {}, copy(iter_tbl) + for i = #iter_tbl, 2, -1 do + local item = iter_tbl[i] + if (_G["sym?"](item, "&into") or ("into" == item)) then + assert(not found_3f, "expected only one &into clause") + found_3f = true + into = iter_tbl[(i + 1)] + table.remove(iter_out, i) + table.remove(iter_out, i) + end + end + assert((not found_3f or _G["sym?"](into) or _G["table?"](into) or _G["list?"](into)), "expected table, function call, or symbol in &into clause") + return into, iter_out, found_3f + end + utils['fennel-module'].metadata:setall(extract_into, "fnl/arglist", {"iter-tbl"}) + local function collect_2a(iter_tbl, key_expr, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 <= #iter_tbl)), "expected iterator binding table") + assert((nil ~= key_expr), "expected key and value expression") + assert((nil == ...), "expected 1 or 2 body expressions; wrap multiple expressions with do") + assert((value_expr or _G["list?"](key_expr)), "need key and value") + local kv_expr = nil + if (nil == value_expr) then + kv_expr = key_expr + else + kv_expr = setmetatable({filename="src/fennel/macros.fnl", line=151, bytestart=5514, sym('values', nil, {quoted=true, filename="src/fennel/macros.fnl", line=151}), key_expr, value_expr}, getmetatable(list())) + end + local into, iter = extract_into(iter_tbl) + return setmetatable({filename="src/fennel/macros.fnl", line=153, bytestart=5596, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=153}), setmetatable({sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=153}), into}, {filename="src/fennel/macros.fnl", line=153}), setmetatable({filename="src/fennel/macros.fnl", line=154, bytestart=5621, sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=154}), iter, setmetatable({filename="src/fennel/macros.fnl", line=155, bytestart=5642, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=155}), setmetatable({setmetatable({filename="src/fennel/macros.fnl", line=155, bytestart=5648, sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=155}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=155})}, getmetatable(list())), kv_expr}, {filename="src/fennel/macros.fnl", line=155}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5677, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5681, sym('and', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5686, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=156}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5700, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=156}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=157, bytestart=5728, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=157}), sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=157}), sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=157}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=157})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=158})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(collect_2a, "fnl/arglist", {"iter-tbl", "key-expr", "value-expr", "..."}, "fnl/docstring", "Return a table made by running an iterator and evaluating an expression that\nreturns key-value pairs to be inserted sequentially into the table. This can\nbe thought of as a table comprehension. The body should provide two expressions\n(used as key and value) or nil, which causes it to be omitted.\n\nFor example,\n (collect [k v (pairs {:apple \"red\" :orange \"orange\"})]\n (values v k))\nreturns\n {:red \"apple\" :orange \"orange\"}\n\nSupports an &into clause after the iterator to put results in an existing table.\nSupports early termination with an &until clause.") + local function seq_collect(how, iter_tbl, value_expr, ...) + assert((nil ~= value_expr), "expected table value expression") + assert((nil == ...), "expected exactly one body expression. Wrap multiple expressions in do") + local into, iter, has_into_3f = extract_into(iter_tbl) + if has_into_3f then + return setmetatable({filename="src/fennel/macros.fnl", line=170, bytestart=6252, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=170}), setmetatable({sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=170}), into}, {filename="src/fennel/macros.fnl", line=170}), setmetatable({filename="src/fennel/macros.fnl", line=171, bytestart=6281, how, iter, setmetatable({filename="src/fennel/macros.fnl", line=171, bytestart=6293, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=171}), setmetatable({sym('val_20_', nil, {filename="src/fennel/macros.fnl", line=171}), value_expr}, {filename="src/fennel/macros.fnl", line=171}), setmetatable({filename="src/fennel/macros.fnl", line=172, bytestart=6342, sym('table.insert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=172}), sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=172}), sym('val_20_', nil, {filename="src/fennel/macros.fnl", line=172})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=173})}, getmetatable(list())) + else + return setmetatable({filename="src/fennel/macros.fnl", line=177, bytestart=6618, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=177}), setmetatable({sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=177}), setmetatable({}, {filename="src/fennel/macros.fnl", line=177})}, {filename="src/fennel/macros.fnl", line=177}), setmetatable({filename="src/fennel/macros.fnl", line=178, bytestart=6644, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=178}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=178}), 0}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=179, bytestart=6666, how, iter, setmetatable({filename="src/fennel/macros.fnl", line=180, bytestart=6695, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=180}), setmetatable({sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=180}), value_expr}, {filename="src/fennel/macros.fnl", line=180}), setmetatable({filename="src/fennel/macros.fnl", line=181, bytestart=6738, sym('when', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), setmetatable({filename="src/fennel/macros.fnl", line=181, bytestart=6744, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=181})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=182, bytestart=6781, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=182}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=182}), setmetatable({filename="src/fennel/macros.fnl", line=182, bytestart=6789, sym('+', nil, {quoted=true, filename="src/fennel/macros.fnl", line=182}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=182}), 1}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=183, bytestart=6820, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=183}), sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=183}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=183}), sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=183})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=184})}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(seq_collect, "fnl/arglist", {"how", "iter-tbl", "value-expr", "..."}, "fnl/docstring", "Common part between icollect and fcollect for producing sequential tables.\n\nIteration code only differs in using the for or each keyword, the rest\nof the generated code is identical.") + local function icollect_2a(iter_tbl, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 <= #iter_tbl)), "expected iterator binding table") + return seq_collect(sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=203}), iter_tbl, value_expr, ...) + end + utils['fennel-module'].metadata:setall(icollect_2a, "fnl/arglist", {"iter-tbl", "value-expr", "..."}, "fnl/docstring", "Return a sequential table made by running an iterator and evaluating an\nexpression that returns values to be inserted sequentially into the table.\nThis can be thought of as a table comprehension. If the body evaluates to nil\nthat element is omitted.\n\nFor example,\n (icollect [_ v (ipairs [1 2 3 4 5])]\n (when (not= v 3)\n (* v v)))\nreturns\n [1 4 16 25]\n\nSupports an &into clause after the iterator to put results in an existing table.\nSupports early termination with an &until clause.") + local function fcollect_2a(iter_tbl, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 < #iter_tbl)), "expected range binding table") + return seq_collect(sym('for', nil, {quoted=true, filename="src/fennel/macros.fnl", line=222}), iter_tbl, value_expr, ...) + end + utils['fennel-module'].metadata:setall(fcollect_2a, "fnl/arglist", {"iter-tbl", "value-expr", "..."}, "fnl/docstring", "Return a sequential table made by advancing a range as specified by\nfor, and evaluating an expression that returns values to be inserted\nsequentially into the table. This can be thought of as a range\ncomprehension. If the body evaluates to nil that element is omitted.\n\nFor example,\n (fcollect [i 1 10 2]\n (when (not= i 3)\n (* i i)))\nreturns\n [1 25 49 81]\n\nSupports an &into clause after the range to put results in an existing table.\nSupports early termination with an &until clause.") + local function accumulate_impl(for_3f, iter_tbl, body, ...) + assert((_G["sequence?"](iter_tbl) and (4 <= #iter_tbl)), "expected initial value and iterator binding table") + assert((nil ~= body), "expected body expression") + assert((nil == ...), "expected exactly one body expression. Wrap multiple expressions with do") + local _25_ = iter_tbl + local accum_var = _25_[1] + local accum_init = _25_[2] + local iter = nil + local function _26_(...) + if for_3f then + return "for" + else + return "each" + end + end + iter = sym(_26_(...)) + local function _27_(...) + if _G["list?"](accum_var) then + return list(sym("values"), unpack(accum_var)) + else + return accum_var + end + end + return setmetatable({filename="src/fennel/macros.fnl", line=232, bytestart=8695, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=232}), setmetatable({filename="src/fennel/macros.fnl", line=233, bytestart=8706, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=233}), accum_var, accum_init}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=234, bytestart=8742, iter, {unpack(iter_tbl, 3)}, setmetatable({filename="src/fennel/macros.fnl", line=235, bytestart=8786, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=235}), accum_var, body}, getmetatable(list()))}, getmetatable(list())), _27_(...)}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(accumulate_impl, "fnl/arglist", {"for?", "iter-tbl", "body", "..."}) + local function accumulate_2a(iter_tbl, body, ...) + return accumulate_impl(false, iter_tbl, body, ...) + end + utils['fennel-module'].metadata:setall(accumulate_2a, "fnl/arglist", {"iter-tbl", "body", "..."}, "fnl/docstring", "Accumulation macro.\n\nIt takes a binding table and an expression as its arguments. In the binding\ntable, the first form starts out bound to the second value, which is an initial\naccumulator. The rest are an iterator binding table in the format `each` takes.\n\nIt runs through the iterator in each step of which the given expression is\nevaluated, and the accumulator is set to the value of the expression. It\neventually returns the final value of the accumulator.\n\nFor example,\n (accumulate [total 0\n _ n (pairs {:apple 2 :orange 3})]\n (+ total n))\nreturns 5") + local function faccumulate_2a(iter_tbl, body, ...) + return accumulate_impl(true, iter_tbl, body, ...) + end + utils['fennel-module'].metadata:setall(faccumulate_2a, "fnl/arglist", {"iter-tbl", "body", "..."}, "fnl/docstring", "Identical to accumulate, but after the accumulator the binding table is the\nsame as `for` instead of `each`. Like collect to fcollect, will iterate over a\nnumerical range like `for` rather than an iterator.") + local function partial_2a(f, ...) + assert(f, "expected a function to partially apply") + local bindings = {} + local args = {} + for _, arg in ipairs({...}) do + if utils["idempotent-expr?"](arg) then + table.insert(args, arg) + else + local name = gensym() + table.insert(bindings, name) + table.insert(bindings, arg) + table.insert(args, name) + end + end + local body = list(f, unpack(args)) + table.insert(body, _VARARG) + if (nil == bindings[1]) then + return setmetatable({filename="src/fennel/macros.fnl", line=280, bytestart=10477, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=280}), setmetatable({_VARARG}, {filename="src/fennel/macros.fnl", line=280}), body}, getmetatable(list())) + else + return setmetatable({filename="src/fennel/macros.fnl", line=281, bytestart=10510, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=281}), bindings, setmetatable({filename="src/fennel/macros.fnl", line=282, bytestart=10538, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=282}), setmetatable({_VARARG}, {filename="src/fennel/macros.fnl", line=282}), body}, getmetatable(list()))}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(partial_2a, "fnl/arglist", {"f", "..."}, "fnl/docstring", "Return a function with all arguments partially applied to f.") + local function pick_args_2a(n, f) + if (_G.io and _G.io.stderr) then + do end (_G.io.stderr):write("-- WARNING: pick-args is deprecated and will be removed in the future.\n") + end + local bindings = {} + for i = 1, n do + bindings[i] = gensym() + end + return setmetatable({filename="src/fennel/macros.fnl", line=291, bytestart=10877, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=291}), bindings, setmetatable({filename="src/fennel/macros.fnl", line=291, bytestart=10891, f, unpack(bindings)}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(pick_args_2a, "fnl/arglist", {"n", "f"}, "fnl/docstring", "Create a function of arity n that applies its arguments to f. Deprecated.") + local function lambda_2a(...) + local args = {...} + local args_len = #args + local has_internal_name_3f = _G["sym?"](args[1]) + local arglist = nil + if has_internal_name_3f then + arglist = args[2] + else + arglist = args[1] + end + local metadata_position = nil + if has_internal_name_3f then + metadata_position = 3 + else + metadata_position = 2 + end + local _, check_position = _G["get-function-metadata"]({"lambda", ...}, arglist, metadata_position) + local empty_body_3f = (args_len < check_position) + local function check_21(a) + if _G["table?"](a) then + for _0, a0 in pairs(a) do + check_21(a0) + end + return nil + else + local _33_ + do + local as = tostring(a) + local as1 = as:sub(1, 1) + _33_ = not (("_" == as1) or ("?" == as1) or ("&" == as) or ("..." == as) or ("&as" == as)) + end + if _33_ then + return table.insert(args, check_position, setmetatable({filename="src/fennel/macros.fnl", line=312, bytestart=11826, sym('_G.assert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), setmetatable({filename="src/fennel/macros.fnl", line=312, bytestart=11837, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), a}, getmetatable(list())), ("Missing argument %s on %s:%s"):format(tostring(a), (a.filename or "unknown"), (a.line or "?"))}, getmetatable(list()))) + end + end + end + utils['fennel-module'].metadata:setall(check_21, "fnl/arglist", {"a"}) + assert(("table" == type(arglist)), "expected arg list") + for _0, a in ipairs(arglist) do + check_21(a) + end + if empty_body_3f then + table.insert(args, sym("nil")) + end + return setmetatable({filename="src/fennel/macros.fnl", line=321, bytestart=12271, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=321}), unpack(args)}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(lambda_2a, "fnl/arglist", {"..."}, "fnl/docstring", "Function literal with nil-checked arguments.\nLike `fn`, but will throw an exception if a declared argument is passed in as\nnil, unless that argument's name begins with a question mark.") + local function macro_2a(name, ...) + assert(_G["sym?"](name), "expected symbol for macro name") + local args = {...} + return setmetatable({filename="src/fennel/macros.fnl", line=327, bytestart=12423, sym('macros', nil, {quoted=true, filename="src/fennel/macros.fnl", line=327}), setmetatable({[tostring(name)]=setmetatable({filename="src/fennel/macros.fnl", line=327, bytestart=12449, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=327}), unpack(args)}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=327})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(macro_2a, "fnl/arglist", {"name", "..."}, "fnl/docstring", "Define a single macro.") + local function macrodebug_2a(form, return_3f) + local handle = nil + if return_3f then + handle = sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=332}) + else + handle = sym('print', nil, {quoted=true, filename="src/fennel/macros.fnl", line=332}) + end + return setmetatable({filename="src/fennel/macros.fnl", line=335, bytestart=12845, handle, view(macroexpand(form, _SCOPE), {["detect-cycles?"] = false})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(macrodebug_2a, "fnl/arglist", {"form", "return?"}, "fnl/docstring", "Print the resulting form after performing macroexpansion.\nWith a second argument, returns expanded form as a string instead of printing.") + local function import_macros_2a(binding1, module_name1, ...) + assert((binding1 and module_name1 and (0 == (select("#", ...) % 2))), "expected even number of binding/modulename pairs") + for i = 1, select("#", binding1, module_name1, ...), 2 do + local binding, modname = select(i, binding1, module_name1, ...) + local scope = _G["get-scope"]() + local expr = setmetatable({filename="src/fennel/macros.fnl", line=354, bytestart=14006, sym('import-macros', nil, {quoted=true, filename="src/fennel/macros.fnl", line=354}), modname}, getmetatable(list())) + local filename = nil + if _G["list?"](modname) then + filename = modname[1].filename + else + filename = "unknown" + end + local _ = nil + expr.filename = filename + _ = nil + local macros_2a = _SPECIALS["require-macros"](expr, scope, {}, binding) + if _G["sym?"](binding) then + scope.macros[binding[1]] = macros_2a + elseif _G["table?"](binding) then + for macro_name, _38_0 in pairs(binding) do + local _39_ = _38_0 + local import_key = _39_[1] + assert(("function" == type(macros_2a[macro_name])), ("macro " .. macro_name .. " not found in module " .. tostring(modname))) + scope.macros[import_key] = macros_2a[macro_name] + end + end + end + return nil + end + utils['fennel-module'].metadata:setall(import_macros_2a, "fnl/arglist", {"binding1", "module-name1", "..."}, "fnl/docstring", "Bind a table of macros from each macro module according to a binding form.\nEach binding form can be either a symbol or a k/v destructuring table.\nExample:\n (import-macros mymacros :my-macros ; bind to symbol\n {:macro1 alias : macro2} :proj.macros) ; import by name") + local function assert_repl_2a(condition, ...) + do local _ = {["fnl/arglist"] = {condition, _G["?message"], ...}} end + local function add_locals(_41_0, locals) + local _42_ = _41_0 + local parent = _42_["parent"] + local symmeta = _42_["symmeta"] + for name in pairs(symmeta) do + locals[name] = sym(name) + end + if parent then + return add_locals(parent, locals) + else + return locals + end + end + utils['fennel-module'].metadata:setall(add_locals, "fnl/arglist", {"#", "locals"}) + return setmetatable({filename="src/fennel/macros.fnl", line=379, bytestart=15225, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), setmetatable({sym('unpack_44_', nil, {filename="src/fennel/macros.fnl", line=379}), setmetatable({filename="src/fennel/macros.fnl", line=379, bytestart=15239, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), sym('table.unpack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), sym('_G.unpack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379})}, getmetatable(list())), sym('pack_46_', nil, {filename="src/fennel/macros.fnl", line=380}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15282, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), sym('table.pack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), setmetatable({filename=nil, line=nil, bytestart=nil, sym('hashfn', nil, {quoted=true, filename=nil, line=nil}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15298, sym('doto', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), setmetatable({sym('$...', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380})}, {filename="src/fennel/macros.fnl", line=380}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15311, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), "n", setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15320, sym('select', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), "#", sym('$...', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=383}), setmetatable({filename="src/fennel/macros.fnl", line=383, bytestart=15493, sym('pack_46_', nil, {filename="src/fennel/macros.fnl", line=383}), condition, ...}, getmetatable(list())), sym('condition_47_', nil, {filename="src/fennel/macros.fnl", line=384}), setmetatable({filename="src/fennel/macros.fnl", line=384, bytestart=15537, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=384}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=384}), 1}, getmetatable(list())), sym('message_48_', nil, {filename="src/fennel/macros.fnl", line=385}), setmetatable({filename="src/fennel/macros.fnl", line=385, bytestart=15567, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=385}), setmetatable({filename="src/fennel/macros.fnl", line=385, bytestart=15571, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=385}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=385}), 2}, getmetatable(list())), "assertion failed, entering repl."}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=379}), setmetatable({filename="src/fennel/macros.fnl", line=386, bytestart=15625, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=386}), setmetatable({filename="src/fennel/macros.fnl", line=386, bytestart=15629, sym('not', nil, {quoted=true, filename="src/fennel/macros.fnl", line=386}), sym('condition_47_', nil, {filename="src/fennel/macros.fnl", line=386})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=387, bytestart=15655, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=387}), setmetatable({sym('opts_49_', nil, {filename="src/fennel/macros.fnl", line=387}), setmetatable({["assert-repl?"]=true}, {filename="src/fennel/macros.fnl", line=387}), sym('fennel_50_', nil, {filename="src/fennel/macros.fnl", line=388}), setmetatable({filename="src/fennel/macros.fnl", line=388, bytestart=15711, sym('require', nil, {quoted=true, filename="src/fennel/macros.fnl", line=388}), _G["fennel-module-name"]()}, getmetatable(list())), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=389}), add_locals(_G["get-scope"](), {})}, {filename="src/fennel/macros.fnl", line=387}), setmetatable({filename="src/fennel/macros.fnl", line=390, bytestart=15807, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=390}), sym('opts_49_.message', nil, {filename="src/fennel/macros.fnl", line=390}), setmetatable({filename="src/fennel/macros.fnl", line=390, bytestart=15826, sym('fennel_50_.traceback', nil, {filename="src/fennel/macros.fnl", line=390}), sym('message_48_', nil, {filename="src/fennel/macros.fnl", line=390})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=391, bytestart=15867, sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391}), setmetatable({sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=391}), sym('v_53_', nil, {filename="src/fennel/macros.fnl", line=391}), setmetatable({filename="src/fennel/macros.fnl", line=391, bytestart=15880, sym('pairs', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391}), sym('_G', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391})}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=391}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15905, sym('when', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15911, sym('=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15918, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=392})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15934, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('v_53_', nil, {filename="src/fennel/macros.fnl", line=392})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=393, bytestart=15968, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=393}), sym('opts_49_.env', nil, {filename="src/fennel/macros.fnl", line=393}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=393})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=394, bytestart=16003, sym('_G.assert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=394}), setmetatable({filename="src/fennel/macros.fnl", line=394, bytestart=16014, sym('fennel_50_.repl', nil, {filename="src/fennel/macros.fnl", line=394}), sym('opts_49_', nil, {filename="src/fennel/macros.fnl", line=394})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=395, bytestart=16046, sym('values', nil, {quoted=true, filename="src/fennel/macros.fnl", line=395}), setmetatable({filename="src/fennel/macros.fnl", line=395, bytestart=16054, sym('unpack_44_', nil, {filename="src/fennel/macros.fnl", line=395}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=395}), 1, sym('vals_45_.n', nil, {filename="src/fennel/macros.fnl", line=395})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(assert_repl_2a, "fnl/arglist", {"condition", "..."}, "fnl/docstring", "Enter into a debug REPL and print the message when condition is false/nil.\nWorks as a drop-in replacement for Lua's `assert`.\nREPL `,return` command returns values to assert in place to continue execution.") + return {["->"] = __3e_2a, ["->>"] = __3e_3e_2a, ["-?>"] = __3f_3e_2a, ["-?>>"] = __3f_3e_3e_2a, ["?."] = _3fdot, ["\206\187"] = lambda_2a, ["assert-repl"] = assert_repl_2a, ["import-macros"] = import_macros_2a, ["pick-args"] = pick_args_2a, ["with-open"] = with_open_2a, accumulate = accumulate_2a, collect = collect_2a, doto = doto_2a, faccumulate = faccumulate_2a, fcollect = fcollect_2a, icollect = icollect_2a, lambda = lambda_2a, macro = macro_2a, macrodebug = macrodebug_2a, partial = partial_2a, when = when_2a} + ]===], env) + load_macros([===[local function copy(t) + local tbl_14_ = {} + for k, v in pairs(t) do + local k_15_, v_16_ = k, v + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + return tbl_14_ + end + utils['fennel-module'].metadata:setall(copy, "fnl/arglist", {"t"}) + local function double_eval_safe_3f(x, type) + return (("number" == type) or ("string" == type) or ("boolean" == type) or (_G["sym?"](x) and not _G["multi-sym?"](x))) + end + utils['fennel-module'].metadata:setall(double_eval_safe_3f, "fnl/arglist", {"x", "type"}) + local function with(opts, k) + local _2_0 = copy(opts) + _2_0[k] = true + return _2_0 + end + utils['fennel-module'].metadata:setall(with, "fnl/arglist", {"opts", "k"}) + local function without(opts, k) + local _3_0 = copy(opts) + _3_0[k] = nil + return _3_0 + end + utils['fennel-module'].metadata:setall(without, "fnl/arglist", {"opts", "k"}) + local function case_values(vals, pattern, unifications, case_pattern, opts) + local condition = setmetatable({filename="src/fennel/match.fnl", line=20, bytestart=528, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=20})}, getmetatable(list())) + local bindings = {} + for i, pat in ipairs(pattern) do + local subcondition, subbindings = case_pattern({vals[i]}, pat, unifications, without(opts, "multival?")) + table.insert(condition, subcondition) + local tbl_17_ = bindings + local i_18_ = #tbl_17_ + for _, b in ipairs(subbindings) do + local val_19_ = b + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + end + return condition, bindings + end + utils['fennel-module'].metadata:setall(case_values, "fnl/arglist", {"vals", "pattern", "unifications", "case-pattern", "opts"}) + local function case_table(val, pattern, unifications, case_pattern, opts, _3ftop) + local condition = nil + if ("table" == _3ftop) then + condition = setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1005, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=30})}, getmetatable(list())) + else + condition = setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1012, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1017, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1020, sym('_G.type', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), val}, getmetatable(list())), "table"}, getmetatable(list()))}, getmetatable(list())) + end + local bindings = {} + for k, pat in pairs(pattern) do + if _G["sym?"](pat, "&") then + local rest_pat = pattern[(k + 1)] + local rest_val = setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1195, sym('select', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), k, setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1206, setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1207, sym('or', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), sym('table.unpack', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), sym('_G.unpack', nil, {quoted=true, filename="src/fennel/match.fnl", line=35})}, getmetatable(list())), val}, getmetatable(list()))}, getmetatable(list())) + local subcondition = case_table(setmetatable({filename="src/fennel/match.fnl", line=36, bytestart=1284, sym('pick-values', nil, {quoted=true, filename="src/fennel/match.fnl", line=36}), 1, rest_val}, getmetatable(list())), rest_pat, unifications, case_pattern, without(opts, "multival?")) + if not _G["sym?"](rest_pat) then + table.insert(condition, subcondition) + end + assert((nil == pattern[(k + 2)]), "expected & rest argument before last parameter") + table.insert(bindings, rest_pat) + table.insert(bindings, {rest_val}) + elseif _G["sym?"](k, "&as") then + table.insert(bindings, pat) + table.insert(bindings, val) + elseif (("number" == type(k)) and _G["sym?"](pat, "&as")) then + assert((nil == pattern[(k + 2)]), "expected &as argument before last parameter") + table.insert(bindings, pattern[(k + 1)]) + table.insert(bindings, val) + elseif (("number" ~= type(k)) or (not _G["sym?"](pattern[(k - 1)], "&as") and not _G["sym?"](pattern[(k - 1)], "&"))) then + local subval = setmetatable({filename="src/fennel/match.fnl", line=58, bytestart=2418, sym('.', nil, {quoted=true, filename="src/fennel/match.fnl", line=58}), val, k}, getmetatable(list())) + local subcondition, subbindings = case_pattern({subval}, pat, unifications, without(opts, "multival?")) + table.insert(condition, subcondition) + local tbl_17_ = bindings + local i_18_ = #tbl_17_ + for _, b in ipairs(subbindings) do + local val_19_ = b + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + end + end + return condition, bindings + end + utils['fennel-module'].metadata:setall(case_table, "fnl/arglist", {"val", "pattern", "unifications", "case-pattern", "opts", "?top"}) + local function case_guard(vals, condition, guards, unifications, case_pattern, opts) + if guards[1] then + local pcondition, bindings = case_pattern(vals, condition, unifications, opts) + local condition0 = setmetatable({filename="src/fennel/match.fnl", line=69, bytestart=3002, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=69}), unpack(guards)}, getmetatable(list())) + return setmetatable({filename="src/fennel/match.fnl", line=70, bytestart=3042, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=70}), pcondition, setmetatable({filename="src/fennel/match.fnl", line=71, bytestart=3080, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=71}), bindings, condition0}, getmetatable(list()))}, getmetatable(list())), bindings + else + return case_pattern(vals, condition, unifications, opts) + end + end + utils['fennel-module'].metadata:setall(case_guard, "fnl/arglist", {"vals", "condition", "guards", "unifications", "case-pattern", "opts"}) + local function symbols_in_pattern(pattern) + if _G["list?"](pattern) then + if (_G["sym?"](pattern[1], "where") or _G["sym?"](pattern[1], "=")) then + return symbols_in_pattern(pattern[2]) + elseif _G["sym?"](pattern[2], "?") then + return symbols_in_pattern(pattern[1]) + else + local result = {} + for _, child_pattern in ipairs(pattern) do + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(child_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + return result + end + elseif _G["sym?"](pattern) then + if (not _G["sym?"](pattern, "or") and not _G["sym?"](pattern, "nil")) then + return {[tostring(pattern)] = pattern} + else + return {} + end + elseif (type(pattern) == "table") then + local result = {} + for key_pattern, value_pattern in pairs(pattern) do + do + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(key_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(value_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + return result + else + return {} + end + end + utils['fennel-module'].metadata:setall(symbols_in_pattern, "fnl/arglist", {"pattern"}, "fnl/docstring", "gives the set of symbols inside a pattern") + local function symbols_in_every_pattern(pattern_list, infer_unification_3f) + local _3fsymbols = nil + do + local _3fsymbols0 = nil + for _, pattern in ipairs(pattern_list) do + local in_pattern = symbols_in_pattern(pattern) + if _3fsymbols0 then + for name in pairs(_3fsymbols0) do + if not in_pattern[name] then + _3fsymbols0[name] = nil + end + end + _3fsymbols0 = _3fsymbols0 + else + _3fsymbols0 = in_pattern + end + end + _3fsymbols = _3fsymbols0 + end + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for _, symbol in pairs((_3fsymbols or {})) do + local val_19_ = nil + if not (infer_unification_3f and _G["in-scope?"](symbol)) then + val_19_ = symbol + else + val_19_ = nil + end + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + return tbl_17_ + end + utils['fennel-module'].metadata:setall(symbols_in_every_pattern, "fnl/arglist", {"pattern-list", "infer-unification?"}, "fnl/docstring", "gives a list of symbols that are present in every pattern in the list") + local function case_or(vals, pattern, guards, unifications, case_pattern, opts) + local pattern0 = {unpack(pattern, 2)} + local bindings = symbols_in_every_pattern(pattern0, opts["infer-unification?"]) + if (nil == bindings[1]) then + local condition = nil + do + local tbl_17_ = setmetatable({filename="src/fennel/match.fnl", line=125, bytestart=5354, sym('or', nil, {quoted=true, filename="src/fennel/match.fnl", line=125})}, getmetatable(list())) + local i_18_ = #tbl_17_ + for _, subpattern in ipairs(pattern0) do + local val_19_ = case_pattern(vals, subpattern, unifications, opts) + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + condition = tbl_17_ + end + local _21_ + if guards[1] then + _21_ = setmetatable({filename="src/fennel/match.fnl", line=128, bytestart=5495, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=128}), condition, unpack(guards)}, getmetatable(list())) + else + _21_ = condition + end + return _21_, {} + else + local matched_3f = gensym("matched?") + local bindings_mangled = nil + do + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for _, binding in ipairs(bindings) do + local val_19_ = gensym(tostring(binding)) + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + bindings_mangled = tbl_17_ + end + local pre_bindings = setmetatable({filename="src/fennel/match.fnl", line=135, bytestart=5870, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=135})}, getmetatable(list())) + for _, subpattern in ipairs(pattern0) do + local subcondition, subbindings = case_guard(vals, subpattern, guards, {}, case_pattern, opts) + table.insert(pre_bindings, subcondition) + table.insert(pre_bindings, setmetatable({filename="src/fennel/match.fnl", line=139, bytestart=6116, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=139}), subbindings, setmetatable({filename="src/fennel/match.fnl", line=140, bytestart=6176, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=140}), true, unpack(bindings)}, getmetatable(list()))}, getmetatable(list()))) + end + return matched_3f, {setmetatable({filename="src/fennel/match.fnl", line=142, bytestart=6256, unpack(bindings)}, getmetatable(list())), setmetatable({filename="src/fennel/match.fnl", line=142, bytestart=6278, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=142}), unpack(bindings_mangled)}, getmetatable(list()))}, {setmetatable({filename="src/fennel/match.fnl", line=143, bytestart=6333, matched_3f, unpack(bindings_mangled)}, getmetatable(list())), pre_bindings} + end + end + utils['fennel-module'].metadata:setall(case_or, "fnl/arglist", {"vals", "pattern", "guards", "unifications", "case-pattern", "opts"}) + local function case_pattern(vals, pattern, unifications, opts, _3ftop) + local _25_ = vals + local val = _25_[1] + if (_G["sym?"](pattern) and (_G["sym?"](pattern, "nil") or (opts["infer-unification?"] and _G["in-scope?"](pattern) and not _G["sym?"](pattern, "_")) or (opts["infer-unification?"] and _G["multi-sym?"](pattern) and _G["in-scope?"](_G["multi-sym?"](pattern)[1])))) then + return setmetatable({filename="src/fennel/match.fnl", line=177, bytestart=8254, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=177}), val, pattern}, getmetatable(list())), {} + elseif (_G["sym?"](pattern) and unifications[tostring(pattern)]) then + return setmetatable({filename="src/fennel/match.fnl", line=180, bytestart=8402, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=180}), unifications[tostring(pattern)], val}, getmetatable(list())), {} + elseif _G["sym?"](pattern) then + local wildcard_3f = tostring(pattern):find("^_") + if not wildcard_3f then + unifications[tostring(pattern)] = val + end + local _27_ + if (wildcard_3f or string.find(tostring(pattern), "^?")) then + _27_ = true + else + _27_ = setmetatable({filename="src/fennel/match.fnl", line=186, bytestart=8741, sym('not=', nil, {quoted=true, filename="src/fennel/match.fnl", line=186}), sym("nil"), val}, getmetatable(list())) + end + return _27_, {pattern, val} + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "=") and _G["sym?"](pattern[2])) then + local bind = pattern[2] + _G["assert-compile"]((2 == #pattern), "(=) should take only one argument", pattern) + _G["assert-compile"](not opts["infer-unification?"], "(=) cannot be used inside of match", pattern) + _G["assert-compile"](opts["in-where?"], "(=) must be used in (where) patterns", pattern) + _G["assert-compile"]((_G["sym?"](bind) and not _G["sym?"](bind, "nil") and "= has to bind to a symbol" and bind)) + return setmetatable({filename="src/fennel/match.fnl", line=196, bytestart=9355, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=196}), val, bind}, getmetatable(list())), {} + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where") and _G["list?"](pattern[2]) and _G["sym?"](pattern[2][1], "or")) then + _G["assert-compile"](_3ftop, "can't nest (where) pattern", pattern) + return case_or(vals, pattern[2], {unpack(pattern, 3)}, unifications, case_pattern, with(opts, "in-where?")) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where")) then + _G["assert-compile"](_3ftop, "can't nest (where) pattern", pattern) + return case_guard(vals, pattern[2], {unpack(pattern, 3)}, unifications, case_pattern, with(opts, "in-where?")) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "or")) then + _G["assert-compile"](_3ftop, "can't nest (or) pattern", pattern) + _G["assert-compile"](false, "(or) must be used in (where) patterns", pattern) + return case_or(vals, pattern, {}, unifications, case_pattern, opts) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[2], "?")) then + _G["assert-compile"](opts["legacy-guard-allowed?"], "legacy guard clause not supported in case", pattern) + return case_guard(vals, pattern[1], {unpack(pattern, 3)}, unifications, case_pattern, opts) + elseif _G["list?"](pattern) then + _G["assert-compile"](opts["multival?"], "can't nest multi-value destructuring", pattern) + return case_values(vals, pattern, unifications, case_pattern, opts) + elseif (type(pattern) == "table") then + return case_table(val, pattern, unifications, case_pattern, opts, _3ftop) + else + return setmetatable({filename="src/fennel/match.fnl", line=228, bytestart=11092, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=228}), val, pattern}, getmetatable(list())), {} + end + end + utils['fennel-module'].metadata:setall(case_pattern, "fnl/arglist", {"vals", "pattern", "unifications", "opts", "?top"}, "fnl/docstring", "Take the AST of values and a single pattern and returns a condition\nto determine if it matches as well as a list of bindings to\nintroduce for the duration of the body if it does match.") + local function add_pre_bindings(out, pre_bindings) + if pre_bindings then + local tail = setmetatable({filename="src/fennel/match.fnl", line=237, bytestart=11490, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=237})}, getmetatable(list())) + table.insert(out, true) + table.insert(out, setmetatable({filename="src/fennel/match.fnl", line=239, bytestart=11555, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=239}), pre_bindings, tail}, getmetatable(list()))) + return tail + else + return out + end + end + utils['fennel-module'].metadata:setall(add_pre_bindings, "fnl/arglist", {"out", "pre-bindings"}, "fnl/docstring", "Decide when to switch from the current `if` AST to a new one") + local function case_condition(vals, clauses, match_3f, top_table_3f) + local root = setmetatable({filename="src/fennel/match.fnl", line=248, bytestart=11896, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=248})}, getmetatable(list())) + do + local out = root + for i = 1, #clauses, 2 do + local pattern = clauses[i] + local body = clauses[(i + 1)] + local condition, bindings, pre_bindings = nil, nil, nil + local function _31_() + if top_table_3f then + return "table" + else + return true + end + end + condition, bindings, pre_bindings = case_pattern(vals, pattern, {}, {["infer-unification?"] = match_3f, ["legacy-guard-allowed?"] = match_3f, ["multival?"] = true}, _31_()) + local out0 = add_pre_bindings(out, pre_bindings) + table.insert(out0, condition) + table.insert(out0, setmetatable({filename="src/fennel/match.fnl", line=261, bytestart=12633, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=261}), bindings, body}, getmetatable(list()))) + out = out0 + end + end + return root + end + utils['fennel-module'].metadata:setall(case_condition, "fnl/arglist", {"vals", "clauses", "match?", "top-table?"}, "fnl/docstring", "Construct the actual `if` AST for the given match values and clauses.") + local function count_case_multival(pattern) + if (_G["list?"](pattern) and _G["sym?"](pattern[2], "?")) then + return count_case_multival(pattern[1]) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where")) then + return count_case_multival(pattern[2]) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "or")) then + local longest = 0 + for _, child_pattern in ipairs(pattern) do + longest = math.max(longest, count_case_multival(child_pattern)) + end + return longest + elseif _G["list?"](pattern) then + return #pattern + else + return 1 + end + end + utils['fennel-module'].metadata:setall(count_case_multival, "fnl/arglist", {"pattern"}, "fnl/docstring", "Identify the amount of multival values that a pattern requires.") + local function case_count_syms(clauses) + local patterns = nil + do + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for i = 1, #clauses, 2 do + local val_19_ = clauses[i] + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + patterns = tbl_17_ + end + local longest = 0 + for _, pattern in ipairs(patterns) do + longest = math.max(longest, count_case_multival(pattern)) + end + return longest + end + utils['fennel-module'].metadata:setall(case_count_syms, "fnl/arglist", {"clauses"}, "fnl/docstring", "Find the length of the largest multi-valued clause") + local function maybe_optimize_table(val, clauses) + local _34_ + do + local all = _G["sequence?"](val) + for i = 1, #clauses, 2 do + if not all then break end + local function _35_() + local all2 = next(clauses[i]) + for _, d in ipairs(clauses[i]) do + if not all2 then break end + all2 = (all2 and (not _G["sym?"](d) or not tostring(d):find("^&"))) + end + return all2 + end + all = (_G["sequence?"](clauses[i]) and _35_()) + end + _34_ = all + end + if _34_ then + local function _36_() + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for i = 1, #clauses do + local val_19_ = nil + if (1 == (i % 2)) then + val_19_ = list(unpack(clauses[i])) + else + val_19_ = clauses[i] + end + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + return tbl_17_ + end + return setmetatable({filename="src/fennel/match.fnl", line=293, bytestart=13916, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=293}), unpack(val)}, getmetatable(list())), _36_() + else + return val, clauses + end + end + utils['fennel-module'].metadata:setall(maybe_optimize_table, "fnl/arglist", {"val", "clauses"}) + local function case_impl(match_3f, init_val, ...) + assert((init_val ~= nil), "missing subject") + assert((0 == math.fmod(select("#", ...), 2)), "expected even number of pattern/body pairs") + assert((0 ~= select("#", ...)), "expected at least one pattern/body pair") + local val, clauses = maybe_optimize_table(init_val, {...}) + local vals_count = case_count_syms(clauses) + local skips_multiple_eval_protection_3f = ((vals_count == 1) and double_eval_safe_3f(val)) + if skips_multiple_eval_protection_3f then + return case_condition(list(val), clauses, match_3f, _G["table?"](init_val)) + else + local vals = nil + do + local tbl_17_ = list() + local i_18_ = #tbl_17_ + for _ = 1, vals_count do + local val_19_ = gensym() + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + vals = tbl_17_ + end + return list(sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=315}), {vals, val}, case_condition(vals, clauses, match_3f, _G["table?"](init_val))) + end + end + utils['fennel-module'].metadata:setall(case_impl, "fnl/arglist", {"match?", "init-val", "..."}, "fnl/docstring", "The shared implementation of case and match.") + local function case_2a(val, ...) + return case_impl(false, val, ...) + end + utils['fennel-module'].metadata:setall(case_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Perform pattern matching on val. See reference for details.\n\nSyntax:\n\n(case data-expression\n pattern body\n (where pattern guards*) body\n (where (or pattern patterns*) guards*) body)") + local function match_2a(val, ...) + return case_impl(true, val, ...) + end + utils['fennel-module'].metadata:setall(match_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Perform pattern matching on val, automatically unifying on variables in\nlocal scope. See reference for details.\n\nSyntax:\n\n(match data-expression\n pattern body\n (where pattern guards*) body\n (where (or pattern patterns*) guards*) body)") + local function case_try_step(how, expr, _else, pattern, body, ...) + if ((nil == pattern) and (pattern == body)) then + return expr + else + return setmetatable({filename="src/fennel/match.fnl", line=346, bytestart=15867, setmetatable({filename="src/fennel/match.fnl", line=346, bytestart=15868, sym('fn', nil, {quoted=true, filename="src/fennel/match.fnl", line=346}), setmetatable({_VARARG}, {filename="src/fennel/match.fnl", line=346}), setmetatable({filename="src/fennel/match.fnl", line=347, bytestart=15888, how, _VARARG, pattern, case_try_step(how, body, _else, ...), unpack(_else)}, getmetatable(list()))}, getmetatable(list())), expr}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(case_try_step, "fnl/arglist", {"how", "expr", "else", "pattern", "body", "..."}) + local function case_try_impl(how, expr, pattern, body, ...) + local clauses = {pattern, body, ...} + local last = clauses[#clauses] + local catch = nil + if _G["sym?"]((("table" == type(last)) and last[1]), "catch") then + local _43_ = table.remove(clauses) + local _ = _43_[1] + local e = {(table.unpack or unpack)(_43_, 2)} + catch = e + else + catch = {sym('__44_', nil, {filename="src/fennel/match.fnl", line=357}), _VARARG} + end + assert((0 == math.fmod(#clauses, 2)), "expected every pattern to have a body") + assert((0 == math.fmod(#catch, 2)), "expected every catch pattern to have a body") + return case_try_step(how, expr, catch, unpack(clauses)) + end + utils['fennel-module'].metadata:setall(case_try_impl, "fnl/arglist", {"how", "expr", "pattern", "body", "..."}) + local function case_try_2a(expr, pattern, body, ...) + return case_try_impl(sym('case', nil, {quoted=true, filename="src/fennel/match.fnl", line=375}), expr, pattern, body, ...) + end + utils['fennel-module'].metadata:setall(case_try_2a, "fnl/arglist", {"expr", "pattern", "body", "..."}, "fnl/docstring", "Perform chained pattern matching for a sequence of steps which might fail.\n\nThe values from the initial expression are matched against the first pattern.\nIf they match, the first body is evaluated and its values are matched against\nthe second pattern, etc.\n\nIf there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch\nfrom the steps will be tried against these patterns in sequence as a fallback\njust like a normal match. If there is no catch, the mismatched values will be\nreturned as the value of the entire expression.") + local function match_try_2a(expr, pattern, body, ...) + return case_try_impl(sym('match', nil, {quoted=true, filename="src/fennel/match.fnl", line=388}), expr, pattern, body, ...) + end + utils['fennel-module'].metadata:setall(match_try_2a, "fnl/arglist", {"expr", "pattern", "body", "..."}, "fnl/docstring", "Perform chained pattern matching for a sequence of steps which might fail.\n\nThe values from the initial expression are matched against the first pattern.\nIf they match, the first body is evaluated and its values are matched against\nthe second pattern, etc.\n\nIf there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch\nfrom the steps will be tried against these patterns in sequence as a fallback\njust like a normal match. If there is no catch, the mismatched values will be\nreturned as the value of the entire expression.") + return {["case-try"] = case_try_2a, ["match-try"] = match_try_2a, case = case_2a, match = match_2a} + ]===], env) end return mod diff --git a/docs/manual.md b/docs/manual.md index d71267d..6aa1573 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -12,7 +12,9 @@ $ cd fennel-ls $ make docs-love2d # if you plan to use love2d $ make ``` -will create a bleeding-edge latest git `fennel-ls` binary for you. + +will create a `fennel-ls` executable for you using your default system `lua`; +use `make LUA=luajit` etc to use a different Lua version. Run `make install PREFIX=$HOME` to put it in `~/bin` or `sudo make install` for a systemwide install. diff --git a/fennel b/fennel index cd42496..84455d1 100755 --- a/fennel +++ b/fennel @@ -3,24 +3,24 @@ -- SPDX-FileCopyrightText: Calvin Rose and contributors package.preload["fennel.binary"] = package.preload["fennel.binary"] or function(...) local fennel = require("fennel") - local _879_ = require("fennel.utils") - local copy = _879_["copy"] - local warn = _879_["warn"] + local _894_ = require("fennel.utils") + local copy = _894_["copy"] + local warn = _894_["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 _880_0 = os.execute(cmd) - if (_880_0 == 0) then + local _895_0 = os.execute(cmd) + if (_895_0 == 0) then return true - elseif (_880_0 == true) then + elseif (_895_0 == true) then return true end end local function string__3ec_hex_literal(characters) - local _882_ + local _897_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -31,9 +31,9 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( tbl_17_[i_18_] = val_19_ end end - _882_ = tbl_17_ + _897_ = tbl_17_ end - return table.concat(_882_, ", ") + return table.concat(_897_, ", ") 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) @@ -50,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 _885_0 = rename[open] - if (nil ~= _885_0) then - local renamed = _885_0 + local _900_0 = rename[open] + if (nil ~= _900_0) then + local renamed = _900_0 used_renames[open] = true require_name = renamed else - local _ = _885_0 + local _ = _900_0 require_name = open end end @@ -95,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 _889_ + local _904_ do - _889_ = "(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)))" + _904_ = "(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 = _889_:format(dotpath_noextension) + fennel_loader = _904_:format(dotpath_noextension) local lua_loader = fennel["compile-string"](fennel_loader) - local _890_ = options - local rename_modules = _890_["rename-modules"] + local _905_ = options + local rename_modules = _905_["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) @@ -115,33 +115,34 @@ 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 _892_ + local _907_ do - local _891_0 = shellout((cc .. " -dumpmachine")) - if (nil ~= _891_0) then - _892_ = _891_0:match("mingw") + local _906_0 = shellout((cc .. " -dumpmachine")) + if (nil ~= _906_0) then + _907_ = _906_0:match("mingw") else - _892_ = _891_0 + _907_ = _906_0 end end - if _892_ then + if _907_ then rdynamic, bin_extension, ldl_3f = "", ".exe", false else rdynamic, bin_extension, ldl_3f = "-rdynamic", "", true end local compile_command = nil - local _895_ + local _910_ if ldl_3f then - _895_ = "-ldl" + _910_ = "-ldl" else - _895_ = "" + _910_ = "" end - compile_command = {cc, "-Os", lua_c_path, table.concat(native, " "), static_lua, rdynamic, "-lm", _895_, "-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", _910_, "-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 if not execute(table.concat(compile_command, " ")) then - print("failed:", table.concat(compile_command, " ")) + print("Failed:", table.concat(compile_command, " ")) + print("Ensure CC is set to the C compiler you intend to use.") os.exit(1) end if not os.getenv("FENNEL_DEBUG") then @@ -154,17 +155,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 _900_0 = extension - if (_900_0 == "a") then + local _915_0 = extension + if (_915_0 == "a") then return path - elseif (_900_0 == "o") then + elseif (_915_0 == "o") then return path - elseif (_900_0 == "so") then + elseif (_915_0 == "so") then return path - elseif (_900_0 == "dylib") then + elseif (_915_0 == "dylib") then return path else - local _ = _900_0 + local _ = _915_0 return false end end @@ -196,10 +197,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 _907_ = extract_native_args(args) - local libraries = _907_["libraries"] - local modules = _907_["modules"] - local rename_modules = _907_["rename-modules"] + local _922_ = extract_native_args(args) + local libraries = _922_["libraries"] + local modules = _922_["modules"] + local rename_modules = _922_["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) @@ -209,7 +210,9 @@ package.preload["fennel.binary"] = package.preload["fennel.binary"] or function( end local fennel = nil package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) - local utils = require("fennel.utils") + local _710_ = require("fennel.utils") + local utils = _710_ + local copy = _710_["copy"] local parser = require("fennel.parser") local compiler = require("fennel.compiler") local specials = require("fennel.specials") @@ -225,24 +228,27 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) 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")) + local _712_0 = io.read() + if (nil ~= _712_0) then + local input = _712_0 + return (input .. "\n") + end end local function default_on_values(xs) io.write(table.concat(xs, "\9")) return io.write("\n") end local function default_on_error(errtype, err) - local function _702_() - local _701_0 = errtype - if (_701_0 == "Runtime") then + local function _715_() + local _714_0 = errtype + if (_714_0 == "Runtime") then return (compiler.traceback(tostring(err), 4) .. "\n") else - local _ = _701_0 + local _ = _714_0 return ("%s error: %s\n"):format(errtype, tostring(err)) end end - return io.write(_702_()) + return io.write(_715_()) end local function splice_save_locals(env, lua_source, scope) local saves = nil @@ -282,25 +288,25 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) else gap = " " end - local function _708_() + local function _721_() if next(saves) then return (table.concat(saves, " ") .. gap) else return "" end end - local function _711_() - local _709_0, _710_0 = lua_source:match("^(.*)[\n ](return .*)$") - if ((nil ~= _709_0) and (nil ~= _710_0)) then - local body = _709_0 - local _return = _710_0 + local function _724_() + local _722_0, _723_0 = lua_source:match("^(.*)[\n ](return .*)$") + if ((nil ~= _722_0) and (nil ~= _723_0)) then + local body = _722_0 + local _return = _723_0 return (body .. gap .. table.concat(binds, " ") .. gap .. _return) else - local _ = _709_0 + local _ = _722_0 return lua_source end end - return (_708_() .. _711_()) + return (_721_() .. _724_()) end local commands = {} local function completer(env, scope, text, _3ffulltext, _from, _to) @@ -313,14 +319,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 _713_() + local function _726_() if scope_first_3f then return scope.manglings else return tbl end end - for k, is_mangled in utils.allpairs(_713_()) do + for k, is_mangled in utils.allpairs(_726_()) do if (max_items <= #matches) then break end local val_19_ = nil do @@ -378,12 +384,12 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end end do - local _722_0 = tostring((_3ffulltext or text)):match("^%s*,([^%s()[%]]*)$") - if (nil ~= _722_0) then - local cmd_fragment = _722_0 + local _735_0 = tostring((_3ffulltext or text)):match("^%s*,([^%s()[%]]*)$") + if (nil ~= _735_0) then + local cmd_fragment = _735_0 add_partials(cmd_fragment, commands, ",") else - local _ = _722_0 + local _ = _735_0 for _0, source in ipairs({scope.specials, scope.macros, (env.___replLocals___ or {}), env, env._G}) do if stop_looking_3f then break end add_matches(input_fragment, source) @@ -396,7 +402,7 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return input:match("^%s*,") end local function command_docs() - local _724_ + local _737_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -407,30 +413,30 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) tbl_17_[i_18_] = val_19_ end end - _724_ = tbl_17_ + _737_ = tbl_17_ end - return table.concat(_724_, "\n") + return table.concat(_737_, "\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 ,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 _726_0, _727_0 = pcall(specials["load-code"]("return require(...)", env), module_name) - if ((_726_0 == true) and (nil ~= _727_0)) then - local old = _727_0 + local _739_0, _740_0 = pcall(specials["load-code"]("return require(...)", env), module_name) + if ((_739_0 == true) and (nil ~= _740_0)) then + local old = _740_0 local _ = nil package.loaded[module_name] = nil _ = nil local new = nil do - local _728_0, _729_0 = pcall(require, module_name) - if ((_728_0 == true) and (nil ~= _729_0)) then - local new0 = _729_0 + local _741_0, _742_0 = pcall(require, module_name) + if ((_741_0 == true) and (nil ~= _742_0)) then + local new0 = _742_0 new = new0 - elseif (true and (nil ~= _729_0)) then - local _0 = _728_0 - local msg = _729_0 + elseif (true and (nil ~= _742_0)) then + local _0 = _741_0 + local msg = _742_0 on_error("Repl", msg) new = old else @@ -450,8 +456,8 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) package.loaded[module_name] = old end return on_values({"ok"}) - elseif ((_726_0 == false) and (nil ~= _727_0)) then - local msg = _727_0 + elseif ((_739_0 == false) and (nil ~= _740_0)) then + local msg = _740_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) @@ -459,32 +465,32 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) specials["macro-loaded"][module_name] = nil return nil else - local function _734_() - local _733_0 = msg:gsub("\n.*", "") - return _733_0 + local function _747_() + local _746_0 = msg:gsub("\n.*", "") + return _746_0 end - return on_error("Runtime", _734_()) + return on_error("Runtime", _747_()) end end end local function run_command(read, on_error, f) - local _737_0, _738_0, _739_0 = pcall(read) - if ((_737_0 == true) and (_738_0 == true) and (nil ~= _739_0)) then - local val = _739_0 - local _740_0, _741_0 = pcall(f, val) - if ((_740_0 == false) and (nil ~= _741_0)) then - local msg = _741_0 + local _750_0, _751_0, _752_0 = pcall(read) + if ((_750_0 == true) and (_751_0 == true) and (nil ~= _752_0)) then + local val = _752_0 + local _753_0, _754_0 = pcall(f, val) + if ((_753_0 == false) and (nil ~= _754_0)) then + local msg = _754_0 return on_error("Runtime", msg) end - elseif (_737_0 == false) then + elseif (_750_0 == false) then return on_error("Parse", "Couldn't parse input.") end end commands.reload = function(env, read, on_values, on_error) - local function _744_(_241) + local function _757_(_241) return reload(tostring(_241), env, on_values, on_error) end - return run_command(read, on_error, _744_) + return run_command(read, on_error, _757_) end do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.") commands.reset = function(env, _, on_values) @@ -493,28 +499,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 _745_() + local function _758_() return on_values(completer(env, scope, table.concat(chars):gsub("^%s*,complete%s+", ""):sub(1, -2))) end - return run_command(read, on_error, _745_) + return run_command(read, on_error, _758_) 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 _746_0 = type(subtbl) - if (_746_0 == "function") then + local _759_0 = type(subtbl) + if (_759_0 == "function") then if ((prefix .. name)):match(pattern) then table.insert(names, (prefix .. name)) end - elseif (_746_0 == "table") then + elseif (_759_0 == "table") then if not seen[subtbl] then - local _748_ + local _761_ do seen[subtbl] = true - _748_ = seen + _761_ = seen end - apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _748_, names) + apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _761_, names) end end end @@ -525,10 +531,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return apropos_2a(pattern:gsub("^_G%.", ""), package.loaded, "", {}, {}) end commands.apropos = function(_env, read, on_values, on_error, _scope) - local function _752_(_241) + local function _765_(_241) return on_values(apropos(tostring(_241))) end - return run_command(read, on_error, _752_) + return run_command(read, on_error, _765_) 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) @@ -548,12 +554,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 _755_ + local _768_ do - local _754_0 = path0:gsub("%/", ".") - _755_ = _754_0 + local _767_0 = path0:gsub("%/", ".") + _768_ = _767_0 end - tgt = tgt[_755_] + tgt = tgt[_768_] end return tgt end @@ -565,9 +571,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) do local tgt = apropos_follow_path(path) if ("function" == type(tgt)) then - local _756_0 = (compiler.metadata):get(tgt, "fnl/docstring") - if (nil ~= _756_0) then - local docstr = _756_0 + local _769_0 = (compiler.metadata):get(tgt, "fnl/docstring") + if (nil ~= _769_0) then + local docstr = _769_0 val_19_ = (docstr:match(pattern) and path) else val_19_ = nil @@ -584,10 +590,10 @@ 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 _760_(_241) + local function _773_(_241) return on_values(apropos_doc(tostring(_241))) end - return run_command(read, on_error, _760_) + return run_command(read, on_error, _773_) 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) @@ -601,127 +607,127 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) return nil end commands["apropos-show-docs"] = function(_env, read, on_values, on_error) - local function _762_(_241) + local function _775_(_241) return apropos_show_docs(on_values, tostring(_241)) end - return run_command(read, on_error, _762_) + return run_command(read, on_error, _775_) 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, _763_0, scope) - local _764_ = _763_0 - local env = _764_ - local ___replLocals___ = _764_["___replLocals___"] + local function resolve(identifier, _776_0, scope) + local _777_ = _776_0 + local env = _777_ + local ___replLocals___ = _777_["___replLocals___"] local e = nil - local function _765_(_241, _242) + local function _778_(_241, _242) return (___replLocals___[scope.unmanglings[_242]] or env[_242]) end - e = setmetatable({}, {__index = _765_}) - local function _766_(...) - local _767_0, _768_0 = ... - if ((_767_0 == true) and (nil ~= _768_0)) then - local code = _768_0 - local function _769_(...) - local _770_0, _771_0 = ... - if ((_770_0 == true) and (nil ~= _771_0)) then - local val = _771_0 + e = setmetatable({}, {__index = _778_}) + local function _779_(...) + local _780_0, _781_0 = ... + if ((_780_0 == true) and (nil ~= _781_0)) then + local code = _781_0 + local function _782_(...) + local _783_0, _784_0 = ... + if ((_783_0 == true) and (nil ~= _784_0)) then + local val = _784_0 return val else - local _ = _770_0 + local _ = _783_0 return nil end end - return _769_(pcall(specials["load-code"](code, e))) + return _782_(pcall(specials["load-code"](code, e))) else - local _ = _767_0 + local _ = _780_0 return nil end end - return _766_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) + return _779_(pcall(compiler["compile-string"], tostring(identifier), {scope = scope})) end commands.find = function(env, read, on_values, on_error, scope) - local function _774_(_241) - local _775_0 = nil + local function _787_(_241) + local _788_0 = nil do - local _776_0 = utils["sym?"](_241) - if (nil ~= _776_0) then - local _777_0 = resolve(_776_0, env, scope) - if (nil ~= _777_0) then - _775_0 = debug.getinfo(_777_0) + local _789_0 = utils["sym?"](_241) + if (nil ~= _789_0) then + local _790_0 = resolve(_789_0, env, scope) + if (nil ~= _790_0) then + _788_0 = debug.getinfo(_790_0) else - _775_0 = _777_0 + _788_0 = _790_0 end else - _775_0 = _776_0 + _788_0 = _789_0 end end - if ((_G.type(_775_0) == "table") and (nil ~= _775_0.linedefined) and (nil ~= _775_0.short_src) and (nil ~= _775_0.source) and (_775_0.what == "Lua")) then - local line = _775_0.linedefined - local src = _775_0.short_src - local source = _775_0.source + if ((_G.type(_788_0) == "table") and (nil ~= _788_0.linedefined) and (nil ~= _788_0.short_src) and (nil ~= _788_0.source) and (_788_0.what == "Lua")) then + local line = _788_0.linedefined + local src = _788_0.short_src + local source = _788_0.source local fnlsrc = nil do - local _780_0 = compiler.sourcemap - if (nil ~= _780_0) then - _780_0 = _780_0[source] + local _793_0 = compiler.sourcemap + if (nil ~= _793_0) then + _793_0 = _793_0[source] end - if (nil ~= _780_0) then - _780_0 = _780_0[line] + if (nil ~= _793_0) then + _793_0 = _793_0[line] end - if (nil ~= _780_0) then - _780_0 = _780_0[2] + if (nil ~= _793_0) then + _793_0 = _793_0[2] end - fnlsrc = _780_0 + fnlsrc = _793_0 end return on_values({string.format("%s:%s", src, (fnlsrc or line))}) - elseif (_775_0 == nil) then + elseif (_788_0 == nil) then return on_error("Repl", "Unknown value") else - local _ = _775_0 + local _ = _788_0 return on_error("Repl", "No source info") end end - return run_command(read, on_error, _774_) + return run_command(read, on_error, _787_) 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 _785_(_241) + local function _798_(_241) local name = tostring(_241) local path = (utils["multi-sym?"](name) or {name}) local ok_3f, target = nil, nil - local function _786_() + local function _799_() return (scope.specials[name] or utils["get-in"](scope.macros, path) or resolve(name, env, scope)) end - ok_3f, target = pcall(_786_) + ok_3f, target = pcall(_799_) 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, _785_) + return run_command(read, on_error, _798_) 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(_, read, on_values, on_error, _0, _1, opts) - local function _788_(_241) - local _789_0, _790_0 = pcall(compiler.compile, _241, opts) - if ((_789_0 == true) and (nil ~= _790_0)) then - local result = _790_0 + local function _801_(_241) + local _802_0, _803_0 = pcall(compiler.compile, _241, opts) + if ((_802_0 == true) and (nil ~= _803_0)) then + local result = _803_0 return on_values({result}) - elseif (true and (nil ~= _790_0)) then - local _2 = _789_0 - local msg = _790_0 + elseif (true and (nil ~= _803_0)) then + local _2 = _802_0 + local msg = _803_0 return on_error("Repl", ("Error compiling expression: " .. msg)) end end - return run_command(read, on_error, _788_) + return run_command(read, on_error, _801_) 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 _792_0 = name:match("^repl%-command%-(.*)") - if (nil ~= _792_0) then - local cmd_name = _792_0 + local _805_0 = name:match("^repl%-command%-(.*)") + if (nil ~= _805_0) then + local cmd_name = _805_0 commands[cmd_name] = f end end @@ -731,12 +737,12 @@ 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, opts) local command_name = input:match(",([^%s/]+)") do - local _794_0 = commands[command_name] - if (nil ~= _794_0) then - local command = _794_0 + local _807_0 = commands[command_name] + if (nil ~= _807_0) then + local command = _807_0 command(env, read, on_values, on_error, scope, chars, opts) else - local _ = _794_0 + local _ = _807_0 if ((command_name ~= "exit") and (command_name ~= "return")) then on_values({"Unknown command", command_name}) end @@ -753,15 +759,10 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end readline.set_options({histfile = "", keeplines = 1000}) opts.readChunk = function(parser_state) - local prompt = nil - if (0 < parser_state["stack-size"]) then - prompt = ".. " - else - prompt = ">> " - end - local str = readline.readline(prompt) - if str then - return (str .. "\n") + local _812_0 = readline.readline(prompt_for((0 == parser_state["stack-size"]))) + if (nil ~= _812_0) then + local input = _812_0 + return (input .. "\n") end end local completer0 = nil @@ -786,9 +787,9 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end local function repl(_3foptions) local old_root_options = utils.root.options - local _803_ = utils.copy(_3foptions) - local opts = _803_ - local _3ffennelrc = _803_["fennelrc"] + local _816_ = copy(_3foptions) + local opts = _816_ + local _3ffennelrc = _816_["fennelrc"] local _ = nil opts.fennelrc = nil _ = nil @@ -803,20 +804,20 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) local callbacks = {["view-opts"] = (opts["view-opts"] or {depth = 4}), 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 _805_(_241) + local function _818_(_241) return callbacks.readChunk(_241) end - byte_stream, clear_stream = parser.granulate(_805_) + byte_stream, clear_stream = parser.granulate(_818_) local chars = {} local read, reset = nil, nil - local function _806_(parser_state) + local function _819_(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(_806_) + read, reset = parser.parser(_819_) depth = (depth + 1) if opts.message then callbacks.onValues({opts.message}) @@ -831,14 +832,14 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) opts.init(opts, depth) end if opts.registerCompleter then - local function _812_() - local _811_0 = opts.scope - local function _813_(...) - return completer(env, _811_0, ...) + local function _825_() + local _824_0 = opts.scope + local function _826_(...) + return completer(env, _824_0, ...) end - return _813_ + return _826_ end - opts.registerCompleter(_812_()) + opts.registerCompleter(_825_()) end load_plugin_commands(opts.plugins) if save_locals_3f then @@ -885,28 +886,28 @@ 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, opts) else if not_eof_3f then - local function _817_(...) - local _818_0, _819_0 = ... - if ((_818_0 == true) and (nil ~= _819_0)) then - local src = _819_0 - local function _820_(...) - local _821_0, _822_0 = ... - if ((_821_0 == true) and (nil ~= _822_0)) then - local chunk = _822_0 - local function _823_() + local function _830_(...) + local _831_0, _832_0 = ... + if ((_831_0 == true) and (nil ~= _832_0)) then + local src = _832_0 + local function _833_(...) + local _834_0, _835_0 = ... + if ((_834_0 == true) and (nil ~= _835_0)) then + local chunk = _835_0 + local function _836_() return print_values(save_value(chunk())) end - local function _824_(...) + local function _837_(...) return callbacks.onError("Runtime", ...) end - return xpcall(_823_, _824_) - elseif ((_821_0 == false) and (nil ~= _822_0)) then - local msg = _822_0 + return xpcall(_836_, _837_) + elseif ((_834_0 == false) and (nil ~= _835_0)) then + local msg = _835_0 clear_stream() return callbacks.onError("Compile", msg) end end - local function _827_(...) + local function _840_(...) local src0 = nil if save_locals_3f then src0 = splice_save_locals(env, src, opts.scope) @@ -915,18 +916,18 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return pcall(specials["load-code"], src0, env) end - return _820_(_827_(...)) - elseif ((_818_0 == false) and (nil ~= _819_0)) then - local msg = _819_0 + return _833_(_840_(...)) + elseif ((_831_0 == false) and (nil ~= _832_0)) then + local msg = _832_0 clear_stream() return callbacks.onError("Compile", msg) end end - local function _829_() + local function _842_() opts["source"] = src_string return opts end - _817_(pcall(compiler.compile, form, _829_())) + _830_(pcall(compiler.compile, form, _842_())) utils.root.options = old_root_options if exit_next_3f then return env.___replLocals___["*1"] @@ -946,30 +947,46 @@ package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...) end return value end - local function _835_(overrides, _3fopts) - return repl(utils.copy(_3fopts, utils.copy(overrides))) + local repl_mt = {__index = {repl = repl}} + repl_mt.__call = function(_848_0, _3fopts) + local _849_ = _848_0 + local overrides = _849_ + local view_opts = _849_["view-opts"] + local opts = copy(_3fopts, copy(overrides)) + local _851_ + do + local _850_0 = _3fopts + if (nil ~= _850_0) then + _850_0 = _850_0["view-opts"] + end + _851_ = _850_0 + end + opts["view-opts"] = copy(_851_, copy(view_opts)) + return repl(opts) end - return setmetatable({}, {__call = _835_, __index = {repl = repl}}) + return setmetatable({["view-opts"] = {}}, repl_mt) end package.preload["fennel.specials"] = package.preload["fennel.specials"] or function(...) - local utils = require("fennel.utils") + local _484_ = require("fennel.utils") + local utils = _484_ + local pack = _484_["pack"] + local unpack = _484_["unpack"] local view = require("fennel.view") local parser = require("fennel.parser") local compiler = require("fennel.compiler") - local unpack = (table.unpack or _G.unpack) local SPECIALS = compiler.scopes.global.specials local function str1(x) return tostring(x[1]) end local function wrap_env(env) - local function _475_(_, key) + local function _485_(_, key) if utils["string?"](key) then return env[compiler["global-unmangling"](key)] else return env[key] end end - local function _477_(_, key, value) + local function _487_(_, key, value) if utils["string?"](key) then env[compiler["global-unmangling"](key)] = value return nil @@ -978,28 +995,28 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return nil end end - local function _479_() - local _480_ + local function _489_() + local _490_ do local tbl_14_ = {} for k, v in utils.stablepairs(env) do local k_15_, v_16_ = nil, nil - local _481_ + local _491_ if utils["string?"](k) then - _481_ = compiler["global-unmangling"](k) + _491_ = compiler["global-unmangling"](k) else - _481_ = k + _491_ = k end - k_15_, v_16_ = _481_, v + k_15_, v_16_ = _491_, v if ((k_15_ ~= nil) and (v_16_ ~= nil)) then tbl_14_[k_15_] = v_16_ end end - _480_ = tbl_14_ + _490_ = tbl_14_ end - return next, _480_, nil + return next, _490_, nil end - return setmetatable({}, {__index = _475_, __newindex = _477_, __pairs = _479_}) + return setmetatable({}, {__index = _485_, __newindex = _487_, __pairs = _489_}) end local function fennel_module_name() return (utils.root.options.moduleName or "fennel") @@ -1007,9 +1024,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function current_global_names(_3fenv) local mt = nil do - local _484_0 = getmetatable(_3fenv) - if ((_G.type(_484_0) == "table") and (nil ~= _484_0.__pairs)) then - local mtpairs = _484_0.__pairs + local _494_0 = getmetatable(_3fenv) + if ((_G.type(_494_0) == "table") and (nil ~= _494_0.__pairs)) then + local mtpairs = _494_0.__pairs local tbl_14_ = {} for k, v in mtpairs(_3fenv) do local k_15_, v_16_ = k, v @@ -1018,13 +1035,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end mt = tbl_14_ - elseif (_484_0 == nil) then + elseif (_494_0 == nil) then mt = (_3fenv or _G) else mt = nil end end - local function _487_() + local function _497_() local tbl_17_ = {} local i_18_ = #tbl_17_ for k in utils.stablepairs(mt) do @@ -1036,19 +1053,19 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - return (mt and _487_()) + return (mt and _497_()) end local function load_code(code, _3fenv, _3ffilename) local env = (_3fenv or rawget(_G, "_ENV") or _G) - local _489_0, _490_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") - if ((nil ~= _489_0) and (nil ~= _490_0)) then - local setfenv = _489_0 - local loadstring = _490_0 + local _499_0, _500_0 = rawget(_G, "setfenv"), rawget(_G, "loadstring") + if ((nil ~= _499_0) and (nil ~= _500_0)) then + local setfenv = _499_0 + local loadstring = _500_0 local f = assert(loadstring(code, _3ffilename)) setfenv(f, env) return f else - local _ = _489_0 + local _ = _499_0 return assert(load(code, _3ffilename, "t", env)) end end @@ -1060,14 +1077,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if not tgt then return (name .. " not found") else - local function _493_() - local _492_0 = getmetatable(tgt) - if ((_G.type(_492_0) == "table") and true) then - local __call = _492_0.__call + local function _503_() + local _502_0 = getmetatable(tgt) + if ((_G.type(_502_0) == "table") and true) then + local __call = _502_0.__call return ("function" == type(__call)) end end - if ((type(tgt) == "function") or _493_()) then + if ((type(tgt) == "function") or _503_()) then local elts = {name, unpack(((compiler.metadata):get(tgt, "fnl/arglist") or {"#"}))} return string.format("(%s)\n %s", table.concat(elts, " "), v__3edocstring(tgt)) else @@ -1138,7 +1155,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("do", {"..."}, "Evaluate multiple forms; return last value.", true) local function iter_args(ast) local ast0, len, i = ast, #ast, 1 - local function _499_() + local function _509_() i = (1 + i) while ((i == len) and utils["call-of?"](ast0[i], "values")) do ast0 = ast0[i] @@ -1147,7 +1164,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return ast0[i], (nil == ast0[(i + 1)]) end - return _499_ + return _509_ end SPECIALS.values = function(ast, scope, parent) local exprs = {} @@ -1191,9 +1208,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 _503_ = compiler.compile1(v, scope, chunk, opts) - local _504_ = _503_[1] - local v0 = _504_[1] + local _513_ = compiler.compile1(v, scope, chunk, opts) + local _514_ = _513_[1] + local v0 = _514_[1] return v0 end local function insert_meta(meta, k, v) @@ -1201,14 +1218,14 @@ 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 _505_() + local function _515_() if ("string" == type(v)) then return view(v, view_opts) else return compile_value(v) end end - table.insert(meta, _505_()) + table.insert(meta, _515_()) return meta end local function insert_arglist(meta, arg_list) @@ -1240,39 +1257,43 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct insert_meta(meta_fields, k, v) end end - local meta_str = ("require(\"%s\").metadata"):format(fennel_module_name()) - return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", "))) + if (type(utils.root.options.useMetadata) == "string") then + return compiler.emit(parent, ("%s:setall(%s, %s)"):format(utils.root.options.useMetadata, fn_name, table.concat(meta_fields, ", "))) + else + local meta_str = ("require(\"%s\").metadata"):format(fennel_module_name()) + return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", "))) + end end end local function get_fn_name(ast, scope, fn_name, multi) if (fn_name and (fn_name[1] ~= "nil")) then - local _509_ + local _520_ if not multi then - _509_ = compiler["declare-local"](fn_name, scope, ast) + _520_ = compiler["declare-local"](fn_name, scope, ast) else - _509_ = compiler["symbol-to-expression"](fn_name, scope)[1] + _520_ = compiler["symbol-to-expression"](fn_name, scope)[1] end - return _509_, not multi, 3 + return _520_, not multi, 3 else return nil, true, 2 end end local function compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, local_3f, arg_name_list, f_metadata) - utils.hook("pre-fn", ast, f_scope) + utils.hook("pre-fn", ast, f_scope, parent) 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 _512_ + local _523_ if local_3f then - _512_ = "local function %s(%s)" + _523_ = "local function %s(%s)" else - _512_ = "%s = function(%s)" + _523_ = "%s = function(%s)" end - compiler.emit(parent, string.format(_512_, fn_name, table.concat(arg_name_list, ", ")), ast) + compiler.emit(parent, string.format(_523_, 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) - utils.hook("fn", ast, f_scope) + utils.hook("fn", ast, f_scope, parent) return utils.expr(fn_name, "sym") end local function compile_anonymous_fn(ast, f_scope, f_chunk, parent, index, arg_name_list, f_metadata, scope) @@ -1290,7 +1311,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function get_function_metadata(ast, arg_list, index) - local function _515_(_241, _242) + local function _526_(_241, _242) local tbl_14_ = _241 for k, v in pairs(_242) do local k_15_, v_16_ = k, v @@ -1300,18 +1321,18 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_14_ end - local function _517_(_241, _242) + local function _528_(_241, _242) _241["fnl/docstring"] = _242 return _241 end - return maybe_metadata(ast, utils["kv-table?"], _515_, maybe_metadata(ast, utils["string?"], _517_, {["fnl/arglist"] = arg_list}, index)) + return maybe_metadata(ast, utils["kv-table?"], _526_, maybe_metadata(ast, utils["string?"], _528_, {["fnl/arglist"] = arg_list}, index)) end SPECIALS.fn = function(ast, scope, parent, opts) local f_scope = nil do - local _518_0 = compiler["make-scope"](scope) - _518_0["vararg"] = false - f_scope = _518_0 + local _529_0 = compiler["make-scope"](scope) + _529_0["vararg"] = false + f_scope = _529_0 end local f_chunk = {} local fn_sym = utils["sym?"](ast[2]) @@ -1374,28 +1395,28 @@ 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 _524_ + local _535_ do - local _523_0 = utils["sym?"](ast[2]) - if (nil ~= _523_0) then - _524_ = tostring(_523_0) + local _534_0 = utils["sym?"](ast[2]) + if (nil ~= _534_0) then + _535_ = tostring(_534_0) else - _524_ = _523_0 + _535_ = _534_0 end end - if ("nil" ~= _524_) then + if ("nil" ~= _535_) then table.insert(parent, {ast = ast, leaf = tostring(ast[2])}) end - local _528_ + local _539_ do - local _527_0 = utils["sym?"](ast[3]) - if (nil ~= _527_0) then - _528_ = tostring(_527_0) + local _538_0 = utils["sym?"](ast[3]) + if (nil ~= _538_0) then + _539_ = tostring(_538_0) else - _528_ = _527_0 + _539_ = _538_0 end end - if ("nil" ~= _528_) then + if ("nil" ~= _539_) then return tostring(ast[3]) end end @@ -1403,8 +1424,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((1 < #ast), "expected table argument", ast) local len = #ast local lhs_node = compiler.macroexpand(ast[2], scope) - local _531_ = compiler.compile1(lhs_node, scope, parent, {nval = 1}) - local lhs = _531_[1] + local _542_ = compiler.compile1(lhs_node, scope, parent, {nval = 1}) + local lhs = _542_[1] if (len == 2) then return tostring(lhs) else @@ -1414,8 +1435,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 _532_ = compiler.compile1(index, scope, parent, {nval = 1}) - local index0 = _532_[1] + local _543_ = compiler.compile1(index, scope, parent, {nval = 1}) + local index0 = _543_[1] table.insert(indices, ("[" .. tostring(index0) .. "]")) end end @@ -1462,7 +1483,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 _536_ + local _547_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1478,15 +1499,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _536_ = tbl_17_ + _547_ = tbl_17_ end - return _536_[1] + return _547_[1] end - SPECIALS.let = function(_539_0, scope, parent, opts) - local _540_ = _539_0 - local _ = _540_[1] - local bindings = _540_[2] - local ast = _540_ + SPECIALS.let = function(_550_0, scope, parent, opts) + local _551_ = _550_0 + local _ = _551_[1] + local bindings = _551_[2] + local ast = _551_ compiler.assert((utils["table?"](bindings) and not kv_3f(bindings)), "expected binding sequence", (bindings or ast[1])) compiler.assert(((#bindings % 2) == 0), "expected even number of name/value bindings", bindings) compiler.assert((3 <= #ast), "expected body expression", ast[1]) @@ -1593,8 +1614,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end for i = 2, (#ast - 1), 2 do local condchunk = {} - local _549_ = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1}) - local cond = _549_[1] + local _560_ = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1}) + local cond = _560_[1] local branch = compile_body((i + 1)) branch.cond = cond branch.condchunk = condchunk @@ -1664,10 +1685,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function remove_until_condition(bindings, ast) local _until = nil for i = (#bindings - 1), 3, -1 do - local _555_0 = clause_3f(bindings[i]) - if ((_555_0 == false) or (_555_0 == nil)) then - elseif (nil ~= _555_0) then - local clause = _555_0 + local _566_0 = clause_3f(bindings[i]) + if ((_566_0 == false) or (_566_0 == nil)) then + elseif (nil ~= _566_0) then + local clause = _566_0 compiler.assert(((clause == "until") and not _until), ("unexpected iterator clause: " .. clause), ast) table.remove(bindings, i) _until = table.remove(bindings, i) @@ -1677,8 +1698,8 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local function compile_until(_3fcondition, scope, chunk) if _3fcondition then - local _557_ = compiler.compile1(_3fcondition, scope, chunk, {nval = 1}) - local condition_lua = _557_[1] + local _568_ = compiler.compile1(_3fcondition, scope, chunk, {nval = 1}) + local condition_lua = _568_[1] return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(_3fcondition, "expression")) end end @@ -1811,10 +1832,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function native_method_call(ast, _scope, _parent, target, args) - local _566_ = ast - local _ = _566_[1] - local _0 = _566_[2] - local method_string = _566_[3] + local _577_ = ast + local _ = _577_[1] + local _0 = _577_[2] + local method_string = _577_[3] local call_string = nil if ((target.type == "literal") or (target.type == "varg") or ((target.type == "expression") and not (target[1]):match("[%)%]]$") and not (target[1]):match("%.[%a_][%w_]*$"))) then call_string = "(%s):%s(%s)" @@ -1837,18 +1858,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 _568_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local target = _568_[1] + local _579_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local target = _579_[1] local args = {} for i = 4, #ast do local subexprs = nil - local _569_ + local _580_ if (i ~= #ast) then - _569_ = 1 + _580_ = 1 else - _569_ = nil + _580_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _569_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _580_}) local tbl_17_ = args local i_18_ = #tbl_17_ for _, subexpr in ipairs(subexprs) do @@ -1859,12 +1880,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end end - local _572_0 = method_special_type(ast) - if (_572_0 == "native") then + local _583_0 = method_special_type(ast) + if (_583_0 == "native") then return native_method_call(ast, scope, parent, target, args) - elseif (_572_0 == "nonnative") then + elseif (_583_0 == "nonnative") then return nonnative_method_call(ast, scope, parent, target, args) - elseif (_572_0 == "binding") then + elseif (_583_0 == "binding") then return binding_method_call(ast, scope, parent, target, args) end end @@ -1872,7 +1893,7 @@ 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 _574_ + local _585_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -1888,9 +1909,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _574_ = tbl_17_ + _585_ = tbl_17_ end - c = table.concat(_574_, " "):gsub("%]%]", "]\\]") + c = table.concat(_585_, " "):gsub("%]%]", "]\\]") return compiler.emit(parent, ("--[[ " .. c .. " ]]"), ast) end doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true) @@ -1911,10 +1932,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 _579_0 = compiler["make-scope"](scope) - _579_0["vararg"] = false - _579_0["hashfn"] = true - f_scope = _579_0 + local _590_0 = compiler["make-scope"](scope) + _590_0["vararg"] = false + _590_0["hashfn"] = true + f_scope = _590_0 end local f_chunk = {} local name = compiler.gensym(scope) @@ -1976,33 +1997,33 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return ok elseif utils["list?"](x) then if utils["sym?"](x[1]) then - local _585_0 = str1(x) - if ((_585_0 == "fn") or (_585_0 == "hashfn") or (_585_0 == "let") or (_585_0 == "local") or (_585_0 == "var") or (_585_0 == "set") or (_585_0 == "tset") or (_585_0 == "if") or (_585_0 == "each") or (_585_0 == "for") or (_585_0 == "while") or (_585_0 == "do") or (_585_0 == "lua") or (_585_0 == "global")) then + local _596_0 = str1(x) + if ((_596_0 == "fn") or (_596_0 == "hashfn") or (_596_0 == "let") or (_596_0 == "local") or (_596_0 == "var") or (_596_0 == "set") or (_596_0 == "tset") or (_596_0 == "if") or (_596_0 == "each") or (_596_0 == "for") or (_596_0 == "while") or (_596_0 == "do") or (_596_0 == "lua") or (_596_0 == "global")) then return false - elseif (((_585_0 == "<") or (_585_0 == ">") or (_585_0 == "<=") or (_585_0 == ">=") or (_585_0 == "=") or (_585_0 == "not=") or (_585_0 == "~=")) and (comparator_special_type(x) == "binding")) then + elseif (((_596_0 == "<") or (_596_0 == ">") or (_596_0 == "<=") or (_596_0 == ">=") or (_596_0 == "=") or (_596_0 == "not=") or (_596_0 == "~=")) and (comparator_special_type(x) == "binding")) then return false else - local function _586_() + local function _597_() return (1 ~= x[2]) end - if ((_585_0 == "pick-values") and _586_()) then + if ((_596_0 == "pick-values") and _597_()) then return false else - local function _587_() - local call = _585_0 + local function _598_() + local call = _596_0 return scope.macros[call] end - if ((nil ~= _585_0) and _587_()) then - local call = _585_0 + if ((nil ~= _596_0) and _598_()) then + local call = _596_0 return false else - local function _588_() + local function _599_() return (method_special_type(x) == "binding") end - if ((_585_0 == ":") and _588_()) then + if ((_596_0 == ":") and _599_()) then return false else - local _ = _585_0 + local _ = _596_0 local ok = true for i = 2, #x do if not ok then break end @@ -2024,21 +2045,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end local function operator_special_result(ast, zero_arity, unary_prefix, padded_op, operands) - local _592_0 = #operands - if (_592_0 == 0) then + local _603_0 = #operands + if (_603_0 == 0) then if zero_arity then return utils.expr(zero_arity, "literal") else return compiler.assert(false, "Expected more than 0 arguments", ast) end - elseif (_592_0 == 1) then + elseif (_603_0 == 1) then if unary_prefix then return ("(" .. unary_prefix .. padded_op .. operands[1] .. ")") else return operands[1] end else - local _ = _592_0 + local _ = _603_0 return ("(" .. table.concat(operands, padded_op) .. ")") end end @@ -2046,14 +2067,14 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct if (accumulator ~= expr_string) then compiler.emit(parent, string.format(setter, accumulator, expr_string), ast) end - local function _597_() + local function _608_() if (name == "and") then return accumulator else return ("not " .. accumulator) end end - compiler.emit(parent, ("if %s then"):format(_597_()), subast) + compiler.emit(parent, ("if %s then"):format(_608_()), subast) do local chunk = {} compiler.compile1(subast, scope, chunk, {nval = 1, target = accumulator}) @@ -2089,15 +2110,15 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return operator_special_result(ast, zero_arity, unary_prefix, padded_op, operands) end local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name) - local _603_ + local _614_ do - local _602_0 = (_3flua_name or name) - local function _604_(...) - return operator_special(_602_0, zero_arity, unary_prefix, ...) + local _613_0 = (_3flua_name or name) + local function _615_(...) + return operator_special(_613_0, zero_arity, unary_prefix, ...) end - _603_ = _604_ + _614_ = _615_ end - SPECIALS[name] = _603_ + SPECIALS[name] = _614_ return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.") end define_arithmetic_special("+", "0", "0") @@ -2126,13 +2147,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 _605_ + local _616_ if (i ~= len) then - _605_ = 1 + _616_ = 1 else - _605_ = nil + _616_ = nil end - subexprs = compiler.compile1(ast[i], scope, parent, {nval = _605_}) + subexprs = compiler.compile1(ast[i], scope, parent, {nval = _616_}) local tbl_17_ = operands local i_18_ = #tbl_17_ for _, s in ipairs(subexprs) do @@ -2159,10 +2180,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 _612_(...) + local function _623_(...) return bitop_special(native, name, zero_arity, unary_prefix, ...) end - SPECIALS[name] = _612_ + SPECIALS[name] = _623_ return nil end define_bitop_special("lshift", nil, "1", "<<") @@ -2177,8 +2198,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 _613_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) - local value = _613_[1] + local _624_ = compiler.compile1(ast[2], scope, parent, {nval = 1}) + local value = _624_[1] if utils.root.options.useBitLib then return ("bit.bnot(" .. tostring(value) .. ")") else @@ -2187,15 +2208,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, _615_0, scope, parent) - local _616_ = _615_0 - local _ = _616_[1] - local lhs_ast = _616_[2] - local rhs_ast = _616_[3] - local _617_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) - local lhs = _617_[1] - local _618_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) - local rhs = _618_[1] + local function native_comparator(op, _626_0, scope, parent) + local _627_ = _626_0 + local _ = _627_[1] + local lhs_ast = _627_[2] + local rhs_ast = _627_[3] + local _628_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1}) + local lhs = _628_[1] + local _629_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1}) + local rhs = _629_[1] return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs)) end local function idempotent_comparator(op, chain_op, ast, scope, parent) @@ -2245,7 +2266,7 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end end compiler.emit(parent, string.format("local %s = %s", table.concat(binding_left, ", "), table.concat(binding_right, ", "), ast)) - local _622_ + local _633_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -2256,24 +2277,24 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct tbl_17_[i_18_] = val_19_ end end - _622_ = tbl_17_ + _633_ = tbl_17_ end - return ("(" .. table.concat(_622_, chain) .. ")") + return ("(" .. table.concat(_633_, chain) .. ")") end local function define_comparator_special(name, _3flua_op, _3fchain_op) do local op = (_3flua_op or name) local function opfn(ast, scope, parent) compiler.assert((2 < #ast), "expected at least two arguments", ast) - local _624_0 = comparator_special_type(ast) - if (_624_0 == "native") then + local _635_0 = comparator_special_type(ast) + if (_635_0 == "native") then return native_comparator(op, ast, scope, parent) - elseif (_624_0 == "idempotent") then + elseif (_635_0 == "idempotent") then return idempotent_comparator(op, _3fchain_op, ast, scope, parent) - elseif (_624_0 == "binding") then + elseif (_635_0 == "binding") then return binding_comparator(op, _3fchain_op, ast, scope, parent) else - local _ = _624_0 + local _ = _635_0 return error("internal compiler error. please report this to the fennel devs.") end end @@ -2302,16 +2323,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct doc_special("length", {"x"}, "Returns the length of a table or string.") SPECIALS["~="] = SPECIALS["not="] SPECIALS["#"] = SPECIALS.length + local function compile_time_3f(scope) + return ((scope == compiler.scopes.compiler) or (scope.parent and compile_time_3f(scope.parent))) + end SPECIALS.quote = function(ast, scope, parent) compiler.assert((#ast == 2), "expected one argument", ast) - local runtime, this_scope = true, scope - while this_scope do - this_scope = this_scope.parent - if (this_scope == compiler.scopes.compiler) then - runtime = false - end - end - return compiler["do-quote"](ast[2], scope, parent, runtime) + return compiler["do-quote"](ast[2], scope, parent, not compile_time_3f(scope)) end doc_special("quote", {"x"}, "Quasiquote the following form. Only works in macro/compiler scope.") local macro_loaded = {} @@ -2322,21 +2339,21 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end local safe_require = nil local function safe_compiler_env() - local _628_ + local _638_ do - local _627_0 = rawget(_G, "utf8") - if (nil ~= _627_0) then - _628_ = utils.copy(_627_0) + local _637_0 = rawget(_G, "utf8") + if (nil ~= _637_0) then + _638_ = utils.copy(_637_0) else - _628_ = _627_0 + _638_ = _637_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 = _628_, 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 = _638_, xpcall = xpcall} end local function combined_mt_pairs(env) local combined = {} - local _630_ = getmetatable(env) - local __index = _630_["__index"] + local _640_ = getmetatable(env) + local __index = _640_["__index"] if ("table" == type(__index)) then for k, v in pairs(__index) do combined[k] = v @@ -2350,40 +2367,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 _632_0 = (_3fopts or utils.root.options) - if ((_G.type(_632_0) == "table") and (_632_0["compiler-env"] == "strict")) then + local _642_0 = (_3fopts or utils.root.options) + if ((_G.type(_642_0) == "table") and (_642_0["compiler-env"] == "strict")) then provided = safe_compiler_env() - elseif ((_G.type(_632_0) == "table") and (nil ~= _632_0.compilerEnv)) then - local compilerEnv = _632_0.compilerEnv + elseif ((_G.type(_642_0) == "table") and (nil ~= _642_0.compilerEnv)) then + local compilerEnv = _642_0.compilerEnv provided = compilerEnv - elseif ((_G.type(_632_0) == "table") and (nil ~= _632_0["compiler-env"])) then - local compiler_env = _632_0["compiler-env"] + elseif ((_G.type(_642_0) == "table") and (nil ~= _642_0["compiler-env"])) then + local compiler_env = _642_0["compiler-env"] provided = compiler_env else - local _ = _632_0 + local _ = _642_0 provided = safe_compiler_env() end end local env = nil - local function _634_() + local function _644_() return compiler.scopes.macro end - local function _635_(symbol) + local function _645_(symbol) compiler.assert(compiler.scopes.macro, "must call from macro", ast) return compiler.scopes.macro.manglings[tostring(symbol)] end - local function _636_(base) + local function _646_(base) return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base)) end - local function _637_(form) + local function _647_(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?"], ["fennel-module-name"] = fennel_module_name, ["get-scope"] = _634_, ["in-scope?"] = _635_, ["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 = _636_, list = utils.list, macroexpand = _637_, 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?"], ["fennel-module-name"] = fennel_module_name, ["get-scope"] = _644_, ["in-scope?"] = _645_, ["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 = _646_, list = utils.list, macroexpand = _647_, pack = pack, 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 _638_(...) + local function _648_(...) local tbl_17_ = {} local i_18_ = #tbl_17_ for c in string.gmatch((package.config or ""), "([^\n]+)") do @@ -2395,10 +2412,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return tbl_17_ end - local _640_ = _638_(...) - local dirsep = _640_[1] - local pathsep = _640_[2] - local pathmark = _640_[3] + local _650_ = _648_(...) + local dirsep = _650_[1] + local pathsep = _650_[2] + local pathmark = _650_[3] local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or "?"), pathsep = (pathsep or ";")} local function escapepat(str) return string.gsub(str, "[^%w]", "%%%1") @@ -2410,37 +2427,36 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local fullpath = ((_3fpathstring or utils["fennel-module"].path) .. pkg_config.pathsep) 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 _641_0 = (io.open(filename) or io.open(filename2)) - if (nil ~= _641_0) then - local file = _641_0 + local _651_0 = io.open(filename) + if (nil ~= _651_0) then + local file = _651_0 file:close() return filename else - local _ = _641_0 + local _ = _651_0 return nil, ("no file '" .. filename .. "'") end end local function find_in_path(start, _3ftried_paths) - local _643_0 = fullpath:match(pattern, start) - if (nil ~= _643_0) then - local path = _643_0 - local _644_0, _645_0 = try_path(path) - if (nil ~= _644_0) then - local filename = _644_0 + local _653_0 = fullpath:match(pattern, start) + if (nil ~= _653_0) then + local path = _653_0 + local _654_0, _655_0 = try_path(path) + if (nil ~= _654_0) then + local filename = _654_0 return filename - elseif ((_644_0 == nil) and (nil ~= _645_0)) then - local error = _645_0 - local function _647_() - local _646_0 = (_3ftried_paths or {}) - table.insert(_646_0, error) - return _646_0 + elseif ((_654_0 == nil) and (nil ~= _655_0)) then + local error = _655_0 + local function _657_() + local _656_0 = (_3ftried_paths or {}) + table.insert(_656_0, error) + return _656_0 end - return find_in_path((start + #path + 1), _647_()) + return find_in_path((start + #path + 1), _657_()) end else - local _ = _643_0 - local function _649_() + local _ = _653_0 + local function _659_() local tried_paths = table.concat((_3ftried_paths or {}), "\n\9") if (_VERSION < "Lua 5.4") then return ("\n\9" .. tried_paths) @@ -2448,31 +2464,31 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return tried_paths end end - return nil, _649_() + return nil, _659_() end end return find_in_path(1) end local function make_searcher(_3foptions) - local function _652_(module_name) + local function _662_(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 _653_0, _654_0 = search_module(module_name) - if (nil ~= _653_0) then - local filename = _653_0 - local function _655_(...) + local _663_0, _664_0 = search_module(module_name) + if (nil ~= _663_0) then + local filename = _663_0 + local function _665_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - return _655_, filename - elseif ((_653_0 == nil) and (nil ~= _654_0)) then - local error = _654_0 + return _665_, filename + elseif ((_663_0 == nil) and (nil ~= _664_0)) then + local error = _664_0 return error end end - return _652_ + return _662_ end local function dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) local searchers = (package.loaders or package.searchers or {}) @@ -2484,35 +2500,35 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local function fennel_macro_searcher(module_name) local opts = nil do - local _657_0 = utils.copy(utils.root.options) - _657_0["module-name"] = module_name - _657_0["env"] = "_COMPILER" - _657_0["requireAsInclude"] = false - _657_0["allowedGlobals"] = nil - opts = _657_0 + local _667_0 = utils.copy(utils.root.options) + _667_0["module-name"] = module_name + _667_0["env"] = "_COMPILER" + _667_0["requireAsInclude"] = false + _667_0["allowedGlobals"] = nil + opts = _667_0 end - local _658_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) - if (nil ~= _658_0) then - local filename = _658_0 - local _659_ + local _668_0 = search_module(module_name, utils["fennel-module"]["macro-path"]) + if (nil ~= _668_0) then + local filename = _668_0 + local _669_ if (opts["compiler-env"] == _G) then - local function _660_(...) + local function _670_(...) return dofile_with_searcher(fennel_macro_searcher, filename, opts, ...) end - _659_ = _660_ + _669_ = _670_ else - local function _661_(...) + local function _671_(...) return utils["fennel-module"].dofile(filename, opts, ...) end - _659_ = _661_ + _669_ = _671_ end - return _659_, filename + return _669_, filename end end local function lua_macro_searcher(module_name) - local _664_0 = search_module(module_name, package.path) - if (nil ~= _664_0) then - local filename = _664_0 + local _674_0 = search_module(module_name, package.path) + if (nil ~= _674_0) then + local filename = _674_0 local code = nil do local f = io.open(filename) @@ -2524,10 +2540,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _666_() + local function _676_() return assert(f:read("*a")) end - code = close_handlers_10_(_G.xpcall(_666_, (package.loaded.fennel or debug).traceback)) + code = close_handlers_10_(_G.xpcall(_676_, (package.loaded.fennel or debug).traceback)) end local chunk = load_code(code, make_compiler_env(), filename) return chunk, filename @@ -2535,38 +2551,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 _668_0 = macro_searchers[n] - if (nil ~= _668_0) then - local f = _668_0 - local _669_0, _670_0 = f(modname) - if ((nil ~= _669_0) and true) then - local loader = _669_0 - local _3ffilename = _670_0 + local _678_0 = macro_searchers[n] + if (nil ~= _678_0) then + local f = _678_0 + local _679_0, _680_0 = f(modname) + if ((nil ~= _679_0) and true) then + local loader = _679_0 + local _3ffilename = _680_0 return loader, _3ffilename else - local _ = _669_0 + local _ = _679_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 - local function _673_(_, ...) + local function _683_(_, ...) return (compiler.metadata):setall(...) end - return {metadata = {setall = _673_}, view = view} + return {metadata = {setall = _683_}, view = view} end end - local function _675_(modname) - local function _676_() + local function _685_(modname) + local function _686_() 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 _676_()) + return (macro_loaded[modname] or sandbox_fennel_module(modname) or _686_()) end - safe_require = _675_ + safe_require = _685_ 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 @@ -2576,10 +2592,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct end return nil end - local function resolve_module_name(_677_0, _scope, _parent, opts) - local _678_ = _677_0 - local second = _678_[2] - local filename = _678_["filename"] + local function resolve_module_name(_687_0, _scope, _parent, opts) + local _688_ = _687_0 + local second = _688_[2] + local filename = _688_["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) @@ -2636,10 +2652,10 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return error(..., 0) end end - local function _684_() + local function _694_() return assert(f:read("*all")):gsub("[\13\n]*$", "") end - src = close_handlers_10_(_G.xpcall(_684_, (package.loaded.fennel or debug).traceback)) + src = close_handlers_10_(_G.xpcall(_694_, (package.loaded.fennel or debug).traceback)) end local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement") local target = ("package.preload[%q]"):format(mod) @@ -2669,12 +2685,12 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct compiler.assert((#ast == 2), "expected one argument", ast) local modexpr = nil do - local _687_0, _688_0 = pcall(resolve_module_name, ast, scope, parent, opts) - if ((_687_0 == true) and (nil ~= _688_0)) then - local modname = _688_0 + local _697_0, _698_0 = pcall(resolve_module_name, ast, scope, parent, opts) + if ((_697_0 == true) and (nil ~= _698_0)) then + local modname = _698_0 modexpr = utils.expr(string.format("%q", modname), "literal") else - local _ = _687_0 + local _ = _697_0 modexpr = compiler.compile1(ast[2], scope, parent, {nval = 1})[1] end end @@ -2691,13 +2707,13 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct utils.root.options["module-name"] = mod _ = nil local res = nil - local function _692_() - local _691_0 = search_module(mod) - if (nil ~= _691_0) then - local fennel_path = _691_0 + local function _702_() + local _701_0 = search_module(mod) + if (nil ~= _701_0) then + local fennel_path = _701_0 return include_path(ast, opts, fennel_path, mod, true) else - local _0 = _691_0 + local _0 = _701_0 local lua_path = search_module(mod, package.path) if lua_path then return include_path(ast, opts, lua_path, mod, false) @@ -2708,7 +2724,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 _692_()) + 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 _702_()) utils.root.options["module-name"] = oldmod return res end @@ -2742,9 +2758,9 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct local vals = utils.list(utils.sym("values"), unpack(ast, 3)) compiler.assert((("number" == type(n)) and (0 <= n) and (n == math.floor(n))), ("Expected n to be an integer >= 0, got " .. tostring(n))) if (1 == n) then - local _696_ = compiler.compile1(vals, scope, parent, {nval = 1}) - local _697_ = _696_[1] - local expr = _697_[1] + local _706_ = compiler.compile1(vals, scope, parent, {nval = 1}) + local _707_ = _706_[1] + local expr = _707_[1] return {("(" .. expr .. ")")} elseif (0 == n) then for i = 3, #ast do @@ -2785,21 +2801,22 @@ package.preload["fennel.specials"] = package.preload["fennel.specials"] or funct return {["current-global-names"] = current_global_names, ["get-function-metadata"] = get_function_metadata, ["load-code"] = load_code, ["macro-loaded"] = macro_loaded, ["macro-searchers"] = macro_searchers, ["make-compiler-env"] = make_compiler_env, ["make-searcher"] = make_searcher, ["search-module"] = search_module, ["wrap-env"] = wrap_env, doc = doc_2a} end package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or function(...) - local utils = require("fennel.utils") + local _281_ = require("fennel.utils") + local utils = _281_ + local unpack = _281_["unpack"] local parser = require("fennel.parser") local friend = require("fennel.friend") local view = require("fennel.view") - local unpack = (table.unpack or _G.unpack) local scopes = {compiler = nil, global = nil, macro = nil} local function make_scope(_3fparent) local parent = (_3fparent or scopes.global) - local _275_ + local _282_ if parent then - _275_ = ((parent.depth or 0) + 1) + _282_ = ((parent.depth or 0) + 1) else - _275_ = 0 + _282_ = 0 end - return {["gensym-base"] = setmetatable({}, {__index = (parent and parent["gensym-base"])}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), depth = _275_, 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 = _282_, 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 @@ -2817,10 +2834,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 _278_ = (utils.root.options or {}) - local error_pinpoint = _278_["error-pinpoint"] - local source = _278_["source"] - local unfriendly = _278_["unfriendly"] + local _285_ = (utils.root.options or {}) + local error_pinpoint = _285_["error-pinpoint"] + local source = _285_["source"] + local unfriendly = _285_["unfriendly"] local ast0 = nil if next(utils["ast-source"](ast)) then ast0 = ast @@ -2842,45 +2859,58 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct scopes.global.vararg = true scopes.compiler = make_scope(scopes.global) scopes.macro = scopes.global + local serialize_subst_digits = {["\\10"] = "\\n", ["\\11"] = "\\v", ["\\12"] = "\\f", ["\\13"] = "\\r", ["\\7"] = "\\a", ["\\8"] = "\\b", ["\\9"] = "\\t"} local function serialize_string(str) - local function _283_(_241) + local function _290_(_241) return ("\\" .. _241:byte()) end - return string.gsub(string.gsub(string.gsub(string.format("%q", str), "\\\n", "\\n"), "\\9", "\\t"), "[\128-\255]", _283_) + return string.gsub(string.gsub(string.gsub(string.format("%q", str), "\\\n", "\\n"), "\\..?", serialize_subst_digits), "[\128-\255]", _290_) end local function global_mangling(str) if utils["valid-lua-identifier?"](str) then return str else - local function _284_(_241) - return string.format("_%02x", _241:byte()) + local _292_ + do + local _291_0 = utils.root.options + if (nil ~= _291_0) then + _291_0 = _291_0["global-mangle"] + end + _292_ = _291_0 + end + if (_292_ == false) then + return ("_G[%q]"):format(str) + else + local function _294_(_241) + return string.format("_%02x", _241:byte()) + end + return ("__fnl_global__" .. str:gsub("[^%w]", _294_)) end - return ("__fnl_global__" .. str:gsub("[^%w]", _284_)) end end local function global_unmangling(identifier) - local _286_0 = string.match(identifier, "^__fnl_global__(.*)$") - if (nil ~= _286_0) then - local rest = _286_0 - local _287_0 = nil - local function _288_(_241) + local _296_0 = string.match(identifier, "^__fnl_global__(.*)$") + if (nil ~= _296_0) then + local rest = _296_0 + local _297_0 = nil + local function _298_(_241) return string.char(tonumber(_241:sub(2), 16)) end - _287_0 = string.gsub(rest, "_[%da-f][%da-f]", _288_) - return _287_0 + _297_0 = rest:gsub("_[%da-f][%da-f]", _298_) + return _297_0 else - local _ = _286_0 + local _ = _296_0 return identifier end end local function global_allowed_3f(name) local allowed = nil do - local _290_0 = utils.root.options - if (nil ~= _290_0) then - _290_0 = _290_0.allowedGlobals + local _300_0 = utils.root.options + if (nil ~= _300_0) then + _300_0 = _300_0.allowedGlobals end - allowed = _290_0 + allowed = _300_0 end return (not allowed or utils["member?"](name, allowed)) end @@ -2944,29 +2974,29 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(parts, ".") end local function autogensym(base, scope) - local _296_0 = utils["multi-sym?"](base) - if (nil ~= _296_0) then - local parts = _296_0 + local _306_0 = utils["multi-sym?"](base) + if (nil ~= _306_0) then + local parts = _306_0 return combine_auto_gensym(parts, autogensym(parts[1], scope)) else - local _ = _296_0 - local function _297_() + local _ = _306_0 + local function _307_() local mangling = gensym(scope, base:sub(1, -2), "auto") scope.autogensyms[base] = mangling return mangling end - return (scope.autogensyms[base] or _297_()) + return (scope.autogensyms[base] or _307_()) end end local function check_binding_valid(symbol, scope, ast, _3fopts) local name = tostring(symbol) local macro_3f = nil do - local _299_0 = _3fopts - if (nil ~= _299_0) then - _299_0 = _299_0["macro?"] + local _309_0 = _3fopts + if (nil ~= _309_0) then + _309_0 = _309_0["macro?"] end - macro_3f = _299_0 + macro_3f = _309_0 end assert_compile(("&" ~= name:match("[&.:]")), "invalid character: &", symbol) assert_compile(not name:find("^%."), "invalid character: .", symbol) @@ -2984,10 +3014,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct raw = str end local mangling = nil - local function _302_(_241) + local function _312_(_241) return string.format("_%02x", _241:byte()) end - mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _302_) + mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _312_) local unique = unique_mangling(mangling, mangling, scope, 0) scope.unmanglings[unique] = (scope["gensym-base"][str] or str) do @@ -3024,14 +3054,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not scope.macros[parts[1]], "tried to reference a macro without calling it", symbol) assert_compile((not scope.specials[parts[1]] or ("require" == parts[1])), "tried to reference a special form without calling it", symbol) assert_compile((not _3freference_3f or local_3f or ("_ENV" == parts[1]) or global_allowed_3f(parts[1])), ("unknown identifier: " .. tostring(parts[1])), symbol) - local function _307_() - local _306_0 = utils.root.options - if (nil ~= _306_0) then - _306_0 = _306_0.allowedGlobals + local function _317_() + local _316_0 = utils.root.options + if (nil ~= _316_0) then + _316_0 = _316_0.allowedGlobals end - return _306_0 + return _316_0 end - if (_307_() and not local_3f and scope.parent) then + if (_317_() and not local_3f and scope.parent) then scope.parent.refedglobals[parts[1]] = true end return utils.expr(combine_parts(parts, scope), etype) @@ -3098,10 +3128,10 @@ 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 _317_ = utils["ast-source"](chunk.ast) - local endline = _317_["endline"] - local filename = _317_["filename"] - local line = _317_["line"] + local _327_ = utils["ast-source"](chunk.ast) + local endline = _327_["endline"] + local filename = _327_["filename"] + local line = _327_["line"] if ("end" == chunk.leaf) then table.insert(file_sourcemap, {filename, (endline or line)}) else @@ -3111,21 +3141,21 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else local tab0 = nil do - local _319_0 = tab - if (_319_0 == true) then + local _329_0 = tab + if (_329_0 == true) then tab0 = " " - elseif (_319_0 == false) then + elseif (_329_0 == false) then tab0 = "" - elseif (nil ~= _319_0) then - local tab1 = _319_0 + elseif (nil ~= _329_0) then + local tab1 = _329_0 tab0 = tab1 - elseif (_319_0 == nil) then + elseif (_329_0 == nil) then tab0 = "" else tab0 = nil end end - local _321_ + local _331_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3146,9 +3176,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _321_ = tbl_17_ + _331_ = tbl_17_ end - return table.concat(_321_, "\n") + return table.concat(_331_, "\n") end end local sourcemap = {} @@ -3179,7 +3209,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function make_metadata() - local function _329_(self, tgt, _3fkey) + local function _339_(self, tgt, _3fkey) if self[tgt] then if (nil ~= _3fkey) then return self[tgt][_3fkey] @@ -3188,12 +3218,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end end - local function _332_(self, tgt, key, value) + local function _342_(self, tgt, key, value) self[tgt] = (self[tgt] or {}) self[tgt][key] = value return tgt end - local function _333_(self, tgt, ...) + local function _343_(self, tgt, ...) local kv_len = select("#", ...) local kvs = {...} if ((kv_len % 2) ~= 0) then @@ -3205,10 +3235,10 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return tgt end - return setmetatable({}, {__index = {get = _329_, set = _332_, setall = _333_}, __mode = "k"}) + return setmetatable({}, {__index = {get = _339_, set = _342_, setall = _343_}, __mode = "k"}) end local function exprs1(exprs) - local _335_ + local _345_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3219,9 +3249,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _335_ = tbl_17_ + _345_ = tbl_17_ end - return table.concat(_335_, ", ") + return table.concat(_345_, ", ") end local function keep_side_effects(exprs, chunk, _3fstart, ast) for j = (_3fstart or 1), #exprs do @@ -3263,14 +3293,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end if opts.target then local result = exprs1(exprs) - local function _343_() + local function _353_() if (result == "") then return "nil" else return result end end - emit(parent, string.format("%s = %s", opts.target, _343_()), ast) + emit(parent, string.format("%s = %s", opts.target, _353_()), ast) end if (opts.tail or opts.target) then return {returned = true} @@ -3282,16 +3312,16 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local function find_macro(ast, scope) local macro_2a = nil do - local _346_0 = utils["sym?"](ast[1]) - if (_346_0 ~= nil) then - local _347_0 = tostring(_346_0) - if (_347_0 ~= nil) then - macro_2a = scope.macros[_347_0] + local _356_0 = utils["sym?"](ast[1]) + if (_356_0 ~= nil) then + local _357_0 = tostring(_356_0) + if (_357_0 ~= nil) then + macro_2a = scope.macros[_357_0] else - macro_2a = _347_0 + macro_2a = _357_0 end else - macro_2a = _346_0 + macro_2a = _356_0 end end local multi_sym_parts = utils["multi-sym?"](ast[1]) @@ -3303,12 +3333,12 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macro_2a end end - local function propagate_trace_info(_351_0, _index, node) - local _352_ = _351_0 - local byteend = _352_["byteend"] - local bytestart = _352_["bytestart"] - local filename = _352_["filename"] - local line = _352_["line"] + local function propagate_trace_info(_361_0, _index, node) + local _362_ = _361_0 + local byteend = _362_["byteend"] + local bytestart = _362_["bytestart"] + local filename = _362_["filename"] + local line = _362_["line"] do local src = utils["ast-source"](node) if (("table" == type(node)) and (filename ~= src.filename)) then @@ -3321,8 +3351,7 @@ 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 _354_0 = parent[i] - if (_354_0 == nil) then + if (nil == parent[i]) then parent[i] = utils.sym("nil") end end @@ -3338,36 +3367,36 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return found_3f end local function macroexpand_2a(ast, scope, _3fonce) - local _357_0 = nil + local _366_0 = nil if utils["list?"](ast) then - _357_0 = find_macro(ast, scope) + _366_0 = find_macro(ast, scope) else - _357_0 = nil + _366_0 = nil end - if (_357_0 == false) then + if (_366_0 == false) then return ast - elseif (nil ~= _357_0) then - local macro_2a = _357_0 + elseif (nil ~= _366_0) then + local macro_2a = _366_0 local old_scope = scopes.macro local _ = nil scopes.macro = scope _ = nil local ok, transformed = nil, nil - local function _359_() + local function _368_() return macro_2a(unpack(ast, 2)) end - local function _360_() + local function _369_() if built_in_3f(macro_2a) then return tostring else return debug.traceback end end - ok, transformed = xpcall(_359_, _360_()) - local function _361_(...) + ok, transformed = xpcall(_368_, _369_()) + local function _370_(...) return propagate_trace_info(ast, quote_literal_nils(...)) end - utils["walk-tree"](transformed, _361_) + utils["walk-tree"](transformed, _370_) scopes.macro = old_scope assert_compile(ok, transformed, ast) utils.hook("macroexpand", ast, transformed, scope) @@ -3377,7 +3406,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return macroexpand_2a(transformed, scope) end else - local _ = _357_0 + local _ = _366_0 return ast end end @@ -3403,9 +3432,9 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return exprs2 end end - local function callable_3f(_367_0, ctype, callee) - local _368_ = _367_0 - local call_ast = _368_[1] + local function callable_3f(_376_0, ctype, callee) + local _377_ = _376_0 + local call_ast = _377_[1] if ("literal" == ctype) then return ("\"" == string.sub(callee, 1, 1)) else @@ -3413,20 +3442,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_function_call(ast, scope, parent, opts, compile1, len) - local _370_ = compile1(ast[1], scope, parent, {nval = 1})[1] - local callee = _370_[1] - local ctype = _370_["type"] + local _379_ = compile1(ast[1], scope, parent, {nval = 1})[1] + local callee = _379_[1] + local ctype = _379_["type"] local fargs = {} assert_compile(callable_3f(ast, ctype, callee), ("cannot call literal value " .. tostring(ast[1])), ast) for i = 2, len do local subexprs = nil - local _371_ + local _380_ if (i ~= len) then - _371_ = 1 + _380_ = 1 else - _371_ = nil + _380_ = nil end - subexprs = compile1(ast[i], scope, parent, {nval = _371_}) + subexprs = compile1(ast[i], scope, parent, {nval = _380_}) table.insert(fargs, subexprs[1]) if (i == len) then for j = 2, #subexprs do @@ -3464,13 +3493,13 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end end local function compile_varg(ast, scope, parent, opts) - local _376_ + local _385_ if scope.hashfn then - _376_ = "use $... in hashfn" + _385_ = "use $... in hashfn" else - _376_ = "unexpected vararg" + _385_ = "unexpected vararg" end - assert_compile(scope.vararg, _376_, ast) + assert_compile(scope.vararg, _385_, ast) return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast) end local function compile_sym(ast, scope, parent, opts) @@ -3487,31 +3516,31 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct local view_opts = nil do local nan = tostring((0 / 0)) - local _379_ + local _388_ if (45 == nan:byte()) then - _379_ = "(0/0)" + _388_ = "(0/0)" else - _379_ = "(- (0/0))" + _388_ = "(- (0/0))" end - local _381_ + local _390_ if (45 == nan:byte()) then - _381_ = "(- (0/0))" + _390_ = "(- (0/0))" else - _381_ = "(0/0)" + _390_ = "(0/0)" end - view_opts = {["negative-infinity"] = "(-1/0)", ["negative-nan"] = _379_, infinity = "(1/0)", nan = _381_} + view_opts = {["negative-infinity"] = "(-1/0)", ["negative-nan"] = _388_, infinity = "(1/0)", nan = _390_} end local function compile_scalar(ast, _scope, parent, opts) local compiled = nil do - local _383_0 = type(ast) - if (_383_0 == "nil") then + local _392_0 = type(ast) + if (_392_0 == "nil") then compiled = "nil" - elseif (_383_0 == "boolean") then + elseif (_392_0 == "boolean") then compiled = tostring(ast) - elseif (_383_0 == "string") then + elseif (_392_0 == "string") then compiled = serialize_string(ast) - elseif (_383_0 == "number") then + elseif (_392_0 == "number") then compiled = view(ast, view_opts) else compiled = nil @@ -3524,8 +3553,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 _385_ = compile1(k, scope, parent, {nval = 1}) - local compiled = _385_[1] + local _394_ = compile1(k, scope, parent, {nval = 1}) + local compiled = _394_[1] return ("[" .. tostring(compiled) .. "]") end end @@ -3554,8 +3583,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct for k in utils.stablepairs(ast) do local val_19_ = nil if not keys[k] then - local _388_ = compile1(ast[k], scope, parent, {nval = 1}) - local v = _388_[1] + local _397_ = compile1(ast[k], scope, parent, {nval = 1}) + local v = _397_[1] val_19_ = string.format("%s = %s", escape_key(k), tostring(v)) else val_19_ = nil @@ -3587,12 +3616,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 _392_ = opts0 - local declaration = _392_["declaration"] - local forceglobal = _392_["forceglobal"] - local forceset = _392_["forceset"] - local isvar = _392_["isvar"] - local symtype = _392_["symtype"] + local _401_ = opts0 + local declaration = _401_["declaration"] + local forceglobal = _401_["forceglobal"] + local forceset = _401_["forceset"] + local isvar = _401_["isvar"] + local symtype = _401_["symtype"] local symtype0 = ("_" .. (symtype or "dst")) local setter = nil if declaration then @@ -3608,8 +3637,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return declare_local(symbol, scope, symbol, isvar, deferred_scope_changes) else local parts = (utils["multi-sym?"](raw) or {raw}) - local _394_ = parts - local first = _394_[1] + local _403_ = parts + local first = _403_[1] local meta = scope.symmeta[first] assert_compile(not raw:find(":"), "cannot set method sym", symbol) if ((#parts == 1) and not forceset) then @@ -3621,24 +3650,24 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not scope.symmeta[scope.unmanglings[raw]], ("global " .. raw .. " conflicts with local"), symbol) scope.manglings[raw] = global_mangling(raw) scope.unmanglings[global_mangling(raw)] = raw - local _397_ + local _406_ do - local _396_0 = utils.root.options - if (nil ~= _396_0) then - _396_0 = _396_0.allowedGlobals + local _405_0 = utils.root.options + if (nil ~= _405_0) then + _405_0 = _405_0.allowedGlobals end - _397_ = _396_0 + _406_ = _405_0 end - if _397_ then - local _400_ + if _406_ then + local _409_ do - local _399_0 = utils.root.options - if (nil ~= _399_0) then - _399_0 = _399_0.allowedGlobals + local _408_0 = utils.root.options + if (nil ~= _408_0) then + _408_0 = _408_0.allowedGlobals end - _400_ = _399_0 + _409_ = _408_0 end - table.insert(_400_, raw) + table.insert(_409_, raw) end end return symbol_to_expression(symbol, scope)[1] @@ -3693,11 +3722,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return emit(parent, setter:format(lname, exprs1(rightexprs)), left) end end - local function dynamic_set_target(_411_0) - local _412_ = _411_0 - local _ = _412_[1] - local target = _412_[2] - local keys = {(table.unpack or unpack)(_412_, 3)} + local function dynamic_set_target(_420_0) + local _421_ = _420_0 + local _ = _421_[1] + local target = _421_[2] + local keys = {(table.unpack or unpack)(_421_, 3)} assert_compile(utils["sym?"](target), "dynamic set needs symbol target", ast) assert_compile(next(keys), "dynamic set needs at least one key", ast) local keys0 = nil @@ -3748,10 +3777,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return nil end - 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 unpack_fn = "function (t, k)\n return ((getmetatable(t) or {}).__fennelrest\n or function (t, k) return {(table.unpack or unpack)(t, k)} end)(t, k)\n end" + local unpack_ks = "function (t, e)\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 end" local function destructure_kv_rest(s, v, left, excluded_keys, destructure1) local exclude_str = nil - local _417_ + local _426_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -3762,25 +3792,25 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct tbl_17_[i_18_] = val_19_ end end - _417_ = tbl_17_ + _426_ = tbl_17_ end - exclude_str = table.concat(_417_, ", ") - local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_fn .. ")(%s, %s, {%s})"), "\n%s*", " "), s, tostring(v), exclude_str), "expression") + exclude_str = table.concat(_426_, ", ") + local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_ks .. ")(%s, {%s})"), "\n%s*", " "), s, exclude_str), "expression") return destructure1(v, {subexpr}, left) end local function destructure_rest(s, k, left, destructure1) local unpack_str = ("(" .. unpack_fn .. ")(%s, %s)") local formatted = string.format(string.gsub(unpack_str, "\n%s*", " "), s, k) local subexpr = utils.expr(formatted, "expression") - local function _419_() + local function _428_() local next_symbol = left[(k + 2)] return ((nil == next_symbol) or utils["sym?"](next_symbol, "&as")) end - assert_compile((utils["sequence?"](left) and _419_()), "expected rest argument before last parameter", left) + assert_compile((utils["sequence?"](left) and _428_()), "expected rest argument before last parameter", left) return destructure1(left[(k + 1)], {subexpr}, left) end local function optimize_table_destructure_3f(left, right) - local function _420_() + local function _429_() local all = next(left) for _, d in ipairs(left) do if not all then break end @@ -3788,24 +3818,25 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end return all end - return (utils["sequence?"](left) and utils["sequence?"](right) and _420_()) + return (utils["sequence?"](left) and utils["sequence?"](right) and _429_()) end local function destructure_table(left, rightexprs, top_3f, destructure1, up1) + assert_compile((("table" == type(rightexprs)) and not utils["sym?"](rightexprs, "nil")), "could not destructure literal", left) if optimize_table_destructure_3f(left, rightexprs) then return destructure_values(utils.list(unpack(left)), utils.list(utils.sym("values"), unpack(rightexprs)), up1, destructure1) else local right = nil do - local _421_0 = nil + local _430_0 = nil if top_3f then - _421_0 = exprs1(compile1(from, scope, parent)) + _430_0 = exprs1(compile1(from, scope, parent)) else - _421_0 = exprs1(rightexprs) + _430_0 = exprs1(rightexprs) end - if (_421_0 == "") then + if (_430_0 == "") then right = "nil" - elseif (nil ~= _421_0) then - local right0 = _421_0 + elseif (nil ~= _430_0) then + local right0 = _430_0 right = right0 else right = nil @@ -3882,7 +3913,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local function compile_asts(asts, options) local opts = utils.copy(options) - local scope = (opts.scope or make_scope(scopes.global)) + local scope = nil + if ("_COMPILER" == opts.scope) then + scope = scopes.compiler + elseif opts.scope then + scope = opts.scope + else + scope = make_scope(scopes.global) + end local chunk = {} if opts.requireAsInclude then scope.specials.require = require_include @@ -3890,8 +3928,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct if opts.assertAsRepl then scope.macros.assert = scope.macros["assert-repl"] end - local _435_ = utils.root - _435_["set-reset"](_435_) + local _445_ = utils.root + _445_["set-reset"](_445_) 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)}) @@ -3924,21 +3962,21 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return compile_stream(parser["string-stream"](str, _3fopts), _3fopts) end local function compile(from, _3fopts) - local _438_0 = type(from) - if (_438_0 == "userdata") then - local function _439_() - local _440_0 = from:read(1) - if (nil ~= _440_0) then - return _440_0:byte() + local _448_0 = type(from) + if (_448_0 == "userdata") then + local function _449_() + local _450_0 = from:read(1) + if (nil ~= _450_0) then + return _450_0:byte() else - return _440_0 + return _450_0 end end - return compile_stream(_439_, _3fopts) - elseif (_438_0 == "function") then + return compile_stream(_449_, _3fopts) + elseif (_448_0 == "function") then return compile_stream(from, _3fopts) else - local _ = _438_0 + local _ = _448_0 return compile_asts({from}, _3fopts) end end @@ -3958,14 +3996,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 _445_() + local function _455_() if info.name then return ("'" .. info.name .. "'") else return "?" end end - return string.format("\9%s:%d: in function %s", info.short_src, info.currentline, _445_()) + return string.format("\9%s:%d: in function %s", info.short_src, info.currentline, _455_()) elseif (info.short_src == "(tail call)") then return " (tail call)" else @@ -3975,8 +4013,8 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct end local lua_getinfo = debug.getinfo local function traceback(_3fmsg, _3fstart) - local _448_0 = type(_3fmsg) - if ((_448_0 == "nil") or (_448_0 == "string")) then + local _458_0 = type(_3fmsg) + if ((_458_0 == "nil") or (_458_0 == "string")) then local msg = (_3fmsg or "") if ((msg:find("^%g+:%d+:%d+ Compile error:.*") or msg:find("^%g+:%d+:%d+ Parse error:.*")) and not utils["debug-on?"]("trace")) then return msg @@ -3992,11 +4030,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 _450_0 = lua_getinfo(level, "Sln") - if (_450_0 == nil) then + local _460_0 = lua_getinfo(level, "Sln") + if (_460_0 == nil) then done_3f = true - elseif (nil ~= _450_0) then - local info = _450_0 + elseif (nil ~= _460_0) then + local info = _460_0 table.insert(lines, traceback_frame(info)) end end @@ -4005,7 +4043,7 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return table.concat(lines, "\n") end else - local _ = _448_0 + local _ = _458_0 return _3fmsg end end @@ -4022,14 +4060,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct for _, key in ipairs({"currentline", "linedefined", "lastlinedefined"}) do local mapped_value = nil do - local _455_0 = mapped - if (nil ~= _455_0) then - _455_0 = _455_0[info[key]] + local _465_0 = mapped + if (nil ~= _465_0) then + _465_0 = _465_0[info[key]] end - if (nil ~= _455_0) then - _455_0 = _455_0[2] + if (nil ~= _465_0) then + _465_0 = _465_0[2] end - mapped_value = _455_0 + mapped_value = _465_0 end if (info[key] and mapped_value) then info[key] = mapped_value @@ -4116,23 +4154,20 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct assert_compile(not runtime_3f, "lists may only be used at compile time", form) return string.format(("setmetatable({filename=%s, line=%s, bytestart=%s, %s}" .. ", getmetatable(_G.list()))"), filename, (form.line or "nil"), (form.bytestart or "nil"), mixed_concat(mapped, ", ")) elseif utils["sequence?"](form) then - local mapped = quote_all(form) + local mapped_str = mixed_concat(quote_all(form), ", ") local source = getmetatable(form) local filename = nil if source.filename then - filename = string.format("%q", source.filename) + filename = ("%q"):format(source.filename) else filename = "nil" end - local _470_ - if source then - _470_ = source.line + if runtime_3f then + return string.format("{%s}", mapped_str) else - _470_ = "nil" + return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mapped_str, filename, (source.line or "nil"), "(getmetatable(_G.sequence()))['sequence']") end - return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _470_, "(getmetatable(_G.sequence()))['sequence']") elseif (type(form) == "table") then - local mapped = quote_all(form) local source = getmetatable(form) local filename = nil if source.filename then @@ -4140,14 +4175,14 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct else filename = "nil" end - local function _473_() + local function _482_() if source then return source.line else return "nil" end end - return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _473_()) + return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(quote_all(form), ", "), filename, _482_()) elseif (type(form) == "string") then return serialize_string(form) else @@ -4157,10 +4192,11 @@ package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or funct return {["apply-deferred-scope-changes"] = apply_deferred_scope_changes, ["check-binding-valid"] = check_binding_valid, ["compile-stream"] = compile_stream, ["compile-string"] = compile_string, ["declare-local"] = declare_local, ["do-quote"] = do_quote, ["global-allowed?"] = global_allowed_3f, ["global-mangling"] = global_mangling, ["global-unmangling"] = global_unmangling, ["keep-side-effects"] = keep_side_effects, ["make-scope"] = make_scope, ["require-include"] = require_include, ["symbol-to-expression"] = symbol_to_expression, assert = assert_compile, autogensym = autogensym, compile = compile, compile1 = compile1, destructure = destructure, emit = emit, gensym = gensym, getinfo = getinfo, macroexpand = macroexpand_2a, metadata = make_metadata(), scopes = scopes, sourcemap = sourcemap, traceback = traceback} end package.preload["fennel.friend"] = package.preload["fennel.friend"] or function(...) - local utils = require("fennel.utils") + local _193_ = require("fennel.utils") + local utils = _193_ + local unpack = _193_["unpack"] local utf8_ok_3f, utf8 = pcall(require, "utf8") local suggestions = {["$ and $... in hashfn are mutually exclusive"] = {"modifying the hashfn so it only contains $... or $, $1, $2, $3, etc"}, ["can't introduce (.*) here"] = {"declaring the local at the top-level"}, ["can't start multisym segment with a digit"] = {"removing the digit", "adding a non-digit before the digit"}, ["cannot call literal value"] = {"checking for typos", "checking for a missing function name", "making sure to use prefix operators, not infix"}, ["could not compile value of type "] = {"debugging the macro you're calling to return a list or table"}, ["could not read number (.*)"] = {"removing the non-digit character", "beginning the identifier with a non-digit if it is not meant to be a number"}, ["expected a function.* to call"] = {"removing the empty parentheses", "using square brackets if you want an empty table"}, ["expected at least one pattern/body pair"] = {"adding a pattern and a body to execute when the pattern matches"}, ["expected binding and iterator"] = {"making sure you haven't omitted a local name or iterator"}, ["expected binding sequence"] = {"placing a table here in square brackets containing identifiers to bind"}, ["expected body expression"] = {"putting some code in the body of this form after the bindings"}, ["expected each macro to be function"] = {"ensuring that the value for each key in your macros table contains a function", "avoid defining nested macro tables"}, ["expected even number of name/value bindings"] = {"finding where the identifier or value is missing"}, ["expected even number of pattern/body pairs"] = {"checking that every pattern has a body to go with it", "adding _ before the final body"}, ["expected even number of values in table literal"] = {"removing a key", "adding a value"}, ["expected local"] = {"looking for a typo", "looking for a local which is used out of its scope"}, ["expected macros to be table"] = {"ensuring your macro definitions return a table"}, ["expected parameters"] = {"adding function parameters as a list of identifiers in brackets"}, ["expected range to include start and stop"] = {"adding missing arguments"}, ["expected rest argument before last parameter"] = {"moving & to right before the final identifier when destructuring"}, ["expected symbol for function parameter: (.*)"] = {"changing %s to an identifier instead of a literal value"}, ["expected var (.*)"] = {"declaring %s using var instead of let/local", "introducing a new local instead of changing the value of %s"}, ["expected vararg as last parameter"] = {"moving the \"...\" to the end of the parameter list"}, ["expected whitespace before opening delimiter"] = {"adding whitespace"}, ["global (.*) conflicts with local"] = {"renaming local %s"}, ["invalid character: (.)"] = {"deleting or replacing %s", "avoiding reserved characters like \", \\, ', ~, ;, @, `, and comma"}, ["local (.*) was overshadowed by a special form or macro"] = {"renaming local %s"}, ["macro not found in macro module"] = {"checking the keys of the imported macro module's returned table"}, ["macro tried to bind (.*) without gensym"] = {"changing to %s# when introducing identifiers inside macros"}, ["malformed multisym"] = {"ensuring each period or colon is not followed by another period or colon"}, ["may only be used at compile time"] = {"moving this to inside a macro if you need to manipulate symbols/lists", "using square brackets instead of parens to construct a table"}, ["method must be last component"] = {"using a period instead of a colon for field access", "removing segments after the colon", "making the method call, then looking up the field on the result"}, ["mismatched closing delimiter (.), expected (.)"] = {"replacing %s with %s", "deleting %s", "adding matching opening delimiter earlier"}, ["missing subject"] = {"adding an item to operate on"}, ["multisym method calls may only be in call position"] = {"using a period instead of a colon to reference a table's fields", "putting parens around this"}, ["tried to reference a macro without calling it"] = {"renaming the macro so as not to conflict with locals"}, ["tried to reference a special form without calling it"] = {"making sure to use prefix operators, not infix", "wrapping the special in a function if you need it to be first class"}, ["tried to use unquote outside quote"] = {"moving the form to inside a quoted form", "removing the comma"}, ["tried to use vararg with operator"] = {"accumulating over the operands"}, ["unable to bind (.*)"] = {"replacing the %s with an identifier"}, ["unexpected arguments"] = {"removing an argument", "checking for typos"}, ["unexpected closing delimiter (.)"] = {"deleting %s", "adding matching opening delimiter earlier"}, ["unexpected iterator clause"] = {"removing an argument", "checking for typos"}, ["unexpected multi symbol (.*)"] = {"removing periods or colons from %s"}, ["unexpected vararg"] = {"putting \"...\" at the end of the fn parameters if the vararg was intended"}, ["unknown identifier: (.*)"] = {"looking to see if there's a typo", "using the _G table instead, eg. _G.%s if you really want a global", "moving this code to somewhere that %s is in scope", "binding %s as a local in the scope of this code"}, ["unused local (.*)"] = {"renaming the local to _%s if it is meant to be unused", "fixing a typo so %s is used", "disabling the linter which checks for unused locals"}, ["use of global (.*) is aliased by a local"] = {"renaming local %s", "refer to the global using _G.%s instead of directly"}} - local unpack = (table.unpack or _G.unpack) local function suggest(msg) local s = nil for pat, sug in pairs(suggestions) do @@ -4200,13 +4236,13 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( return error(..., 0) end end - local function _190_() + local function _197_() for _ = 2, line do f:read() end return f:read() end - return close_handlers_10_(_G.xpcall(_190_, (package.loaded.fennel or debug).traceback)) + return close_handlers_10_(_G.xpcall(_197_, (package.loaded.fennel or debug).traceback)) end end local function sub(str, start, _end) @@ -4222,8 +4258,8 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( if ((opts and (false == opts["error-pinpoint"])) or (os and os.getenv and os.getenv("NO_COLOR"))) then return codeline else - local _193_ = (opts or {}) - local error_pinpoint = _193_["error-pinpoint"] + local _200_ = (opts or {}) + local error_pinpoint = _200_["error-pinpoint"] local endcol = (_3fendcol or col) local eol = nil if utf8_ok_3f then @@ -4231,19 +4267,19 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( else eol = string.len(codeline) end - local _195_ = (error_pinpoint or {"\27[7m", "\27[0m"}) - local open = _195_[1] - local close = _195_[2] + local _202_ = (error_pinpoint or {"\27[7m", "\27[0m"}) + local open = _202_[1] + local close = _202_[2] return (sub(codeline, 1, col) .. open .. sub(codeline, (col + 1), (endcol + 1)) .. close .. sub(codeline, (endcol + 2), eol)) end end - local function friendly_msg(msg, _197_0, source, opts) - local _198_ = _197_0 - local col = _198_["col"] - local endcol = _198_["endcol"] - local endline = _198_["endline"] - local filename = _198_["filename"] - local line = _198_["line"] + local function friendly_msg(msg, _204_0, source, opts) + local _205_ = _204_0 + local col = _205_["col"] + local endcol = _205_["endcol"] + local endline = _205_["endline"] + local filename = _205_["filename"] + local line = _205_["line"] local ok, codeline = pcall(read_line, filename, line, source) local endcol0 = nil if (ok and codeline and (line ~= endline)) then @@ -4266,10 +4302,10 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( end local function assert_compile(condition, msg, ast, source, opts) if not condition then - local _202_ = utils["ast-source"](ast) - local col = _202_["col"] - local filename = _202_["filename"] - local line = _202_["line"] + local _209_ = utils["ast-source"](ast) + local col = _209_["col"] + local filename = _209_["filename"] + local line = _209_["line"] error(friendly_msg(("%s:%s:%s: Compile error: %s"):format((filename or "unknown"), (line or "?"), (col or "?"), msg), utils["ast-source"](ast), source, opts), 0) end return condition @@ -4280,41 +4316,37 @@ package.preload["fennel.friend"] = package.preload["fennel.friend"] or function( return {["assert-compile"] = assert_compile, ["parse-error"] = parse_error} end package.preload["fennel.parser"] = package.preload["fennel.parser"] or function(...) - local utils = require("fennel.utils") + local _192_ = require("fennel.utils") + local utils = _192_ + local unpack = _192_["unpack"] local friend = require("fennel.friend") - local unpack = (table.unpack or _G.unpack) local function granulate(getchunk) local c, index, done_3f = "", 1, false - local function _204_(parser_state) + local function _211_(parser_state) if not done_3f then if (index <= #c) then local b = c:byte(index) index = (index + 1) return b else - local _205_0 = getchunk(parser_state) - local function _206_() - local char = _205_0 - return (char ~= "") - end - if ((nil ~= _205_0) and _206_()) then - local char = _205_0 - c = char - index = 2 + local _212_0 = getchunk(parser_state) + if (nil ~= _212_0) then + local input = _212_0 + c, index = input, 2 return c:byte() else - local _ = _205_0 + local _ = _212_0 done_3f = true return nil end end end end - local function _210_() + local function _216_() c = "" return nil end - return _204_, _210_ + return _211_, _216_ end local function string_stream(str, _3foptions) local str0 = str:gsub("^#!", ";;") @@ -4322,12 +4354,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( _3foptions.source = str0 end local index = 1 - local function _212_() + local function _218_() local r = str0:byte(index) index = (index + 1) return r end - return _212_ + return _218_ end local delims = {[123] = 125, [125] = true, [40] = 41, [41] = true, [91] = 93, [93] = true} local function sym_char_3f(b) @@ -4349,12 +4381,12 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( local function char_starter_3f(b) return (((1 < b) and (b < 127)) or ((192 < b) and (b < 247))) end - local function parser_fn(getbyte, filename, _215_0) - local _216_ = _215_0 - local options = _216_ - local comments = _216_["comments"] - local source = _216_["source"] - local unfriendly = _216_["unfriendly"] + local function parser_fn(getbyte, filename, _221_0) + local _222_ = _221_0 + local options = _222_ + local comments = _222_["comments"] + local source = _222_["source"] + local unfriendly = _222_["unfriendly"] local stack = {} local line, byteindex, col, prev_col, lastb = 1, 0, 0, 0, nil local function ungetb(ub) @@ -4386,15 +4418,18 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return r end + local function warn(...) + return (options.warn or utils.warn)(...) + end local function whitespace_3f(b) - local function _224_() - local _223_0 = options.whitespace - if (nil ~= _223_0) then - _223_0 = _223_0[b] + local function _230_() + local _229_0 = options.whitespace + if (nil ~= _229_0) then + _229_0 = _229_0[b] end - return _223_0 + return _229_0 end - return ((b == 32) or ((9 <= b) and (b <= 13)) or _224_()) + return ((b == 32) or ((9 <= b) and (b <= 13)) or _230_()) end local function parse_error(msg, _3fcol_adjust) local col0 = (col + (_3fcol_adjust or -1)) @@ -4417,31 +4452,31 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( whitespace_since_dispatch = false local v0 = nil do - local _228_0 = utils["hook-opts"]("parse-form", options, v, _3fsource, _3fraw, stack) - if (nil ~= _228_0) then - local hookv = _228_0 + local _234_0 = utils["hook-opts"]("parse-form", options, v, _3fsource, _3fraw, stack) + if (nil ~= _234_0) then + local hookv = _234_0 v0 = hookv else - local _ = _228_0 + local _ = _234_0 v0 = v end end - local _230_0 = stack[#stack] - if (_230_0 == nil) then + local _236_0 = stack[#stack] + if (_236_0 == nil) then retval, done_3f = v0, true return nil - elseif ((_G.type(_230_0) == "table") and (nil ~= _230_0.prefix)) then - local prefix = _230_0.prefix + elseif ((_G.type(_236_0) == "table") and (nil ~= _236_0.prefix)) then + local prefix = _236_0.prefix local source0 = nil do - local _231_0 = table.remove(stack) - set_source_fields(_231_0) - source0 = _231_0 + local _237_0 = table.remove(stack) + set_source_fields(_237_0) + source0 = _237_0 end local list = utils.list(utils.sym(prefix, source0), v0) return dispatch(utils.copy(source0, list)) - elseif (nil ~= _230_0) then - local top = _230_0 + elseif (nil ~= _236_0) then + local top = _236_0 return table.insert(top, v0) end end @@ -4450,9 +4485,9 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( do local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _233_0 in ipairs(stack) do - local _234_ = _233_0 - local closer = _234_["closer"] + for _, _239_0 in ipairs(stack) do + local _240_ = _239_0 + local closer = _240_["closer"] local val_19_ = closer if (nil ~= val_19_) then i_18_ = (i_18_ + 1) @@ -4461,13 +4496,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end closers = tbl_17_ end - local _236_ + local _242_ if (#stack == 1) then - _236_ = "" + _242_ = "" else - _236_ = "s" + _242_ = "s" end - return parse_error(string.format("expected closing delimiter%s %s", _236_, string.char(unpack(closers))), 0) + return parse_error(string.format("expected closing delimiter%s %s", _242_, string.char(unpack(closers))), 0) end local function skip_whitespace(b, close_table) if (b and whitespace_3f(b)) then @@ -4485,11 +4520,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 _239_() + local function _245_() table.insert(contents, string.char(b)) return contents end - return parse_comment(getb(), _239_()) + return parse_comment(getb(), _245_()) elseif comments then ungetb(10) return dispatch(utils.comment(table.concat(contents), {filename = filename, line = line})) @@ -4515,12 +4550,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 _243_0 = comments0[index] - if (nil ~= _243_0) then - local existing = _243_0 + local _249_0 = comments0[index] + if (nil ~= _249_0) then + local existing = _249_0 return table.insert(existing, node) else - local _ = _243_0 + local _ = _249_0 comments0[index] = {node} return nil end @@ -4599,16 +4634,16 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local state0 = nil do - local _254_0 = {state, b} - if ((_G.type(_254_0) == "table") and (_254_0[1] == "base") and (_254_0[2] == 92)) then + local _260_0 = {state, b} + if ((_G.type(_260_0) == "table") and (_260_0[1] == "base") and (_260_0[2] == 92)) then state0 = "backslash" - elseif ((_G.type(_254_0) == "table") and (_254_0[1] == "base") and (_254_0[2] == 34)) then + elseif ((_G.type(_260_0) == "table") and (_260_0[1] == "base") and (_260_0[2] == 34)) then state0 = "done" - elseif ((_G.type(_254_0) == "table") and (_254_0[1] == "backslash") and (_254_0[2] == 10)) then + elseif ((_G.type(_260_0) == "table") and (_260_0[1] == "backslash") and (_260_0[2] == 10)) then table.remove(chars, (#chars - 1)) state0 = "base" else - local _ = _254_0 + local _ = _260_0 state0 = "base" end end @@ -4623,7 +4658,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end local function parse_string(source0) if not whitespace_since_dispatch then - utils.warn("expected whitespace before string", nil, filename, line) + warn("expected whitespace before string", nil, filename, line) end table.insert(stack, {closer = 34}) local chars = {"\""} @@ -4633,11 +4668,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 _259_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) - if (nil ~= _259_0) then - local load_fn = _259_0 + local _265_0 = (rawget(_G, "loadstring") or load)(("return " .. formatted)) + if (nil ~= _265_0) then + local load_fn = _265_0 return dispatch(load_fn(), source0, raw) - elseif (_259_0 == nil) then + elseif (_265_0 == nil) then return parse_error(("Invalid string: " .. raw)) end end @@ -4674,13 +4709,13 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( dispatch((tonumber(trimmed) or parse_error(("could not read number \"" .. rawstr .. "\""))), source0, rawstr) return true else - local _265_0 = tonumber(trimmed) - if (nil ~= _265_0) then - local x = _265_0 + local _271_0 = tonumber(trimmed) + if (nil ~= _271_0) then + local x = _271_0 dispatch(x, source0, rawstr) return true else - local _ = _265_0 + local _ = _271_0 return false end end @@ -4699,7 +4734,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( parse_error(("method must be last component of multisym: " .. rawstr), col_adjust(":.+[%.:]")) end if not whitespace_since_dispatch then - utils.warn("expected whitespace before token", nil, filename, line) + warn("expected whitespace before token", nil, filename, line) end return rawstr end @@ -4754,11 +4789,11 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end return parse_loop(skip_whitespace(getb(), close_table)) end - local function _273_() + local function _279_() stack, line, byteindex, col, lastb = {}, 1, 0, 0, ((lastb ~= 10) and lastb) return nil end - return parse_stream, _273_ + return parse_stream, _279_ end local function parser(stream_or_string, _3ffilename, _3foptions) local filename = (_3ffilename or "unknown") @@ -4774,7 +4809,7 @@ package.preload["fennel.parser"] = package.preload["fennel.parser"] or function( end package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local type_order = {["function"] = 5, boolean = 2, number = 1, string = 3, table = 4, thread = 7, userdata = 6} - local default_opts = {["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["escape-newlines?"] = false, ["line-length"] = 80, ["max-sparse-gap"] = 10, ["metamethod?"] = true, ["one-line?"] = false, ["prefer-colon?"] = false, ["utf8?"] = true, depth = 128} + local default_opts = {["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["escape-newlines?"] = false, ["line-length"] = 80, ["max-sparse-gap"] = 1, ["metamethod?"] = true, ["one-line?"] = false, ["prefer-colon?"] = false, ["utf8?"] = true, depth = 128} local lua_pairs = pairs local lua_ipairs = ipairs local function pairs(t) @@ -4910,11 +4945,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) return nil end local function table_kv_pairs(t, options) + if (("number" ~= type(options["max-sparse-gap"])) or (options["max-sparse-gap"] ~= math.floor(options["max-sparse-gap"]))) then + error(("max-sparse-gap must be an integer: got '%s'"):format(tostring(options["max-sparse-gap"]))) + end local assoc_3f = false local kv = {} local insert = table.insert for k, v in pairs(t) do - if ((type(k) ~= "number") or (k < 1)) then + if (("number" ~= type(k)) or (k < 1) or (k ~= math.floor(k))) then assoc_3f = true end insert(kv, {k, v}) @@ -4930,14 +4968,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) if (length_2a(kv) == 0) then return kv, "empty" else - local function _31_() + local function _32_() if assoc_3f then return "table" else return "seq" end end - return kv, _31_() + return kv, _32_() end end local function count_table_appearances(t, appearances) @@ -4990,14 +5028,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix, last_comment_3f) local indent_str = ("\n" .. string.rep(" ", indent)) local open = nil - local function _38_() + local function _39_() if ("seq" == table_type) then return "[" else return "{" end end - open = ((prefix or "") .. _38_()) + open = ((prefix or "") .. _39_()) local close = nil if ("seq" == table_type) then close = "]" @@ -5006,14 +5044,14 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end local oneline = (open .. table.concat(elements, " ") .. close) if (not getopt(options, "one-line?") and (multiline_3f or (options["line-length"] < (indent + length_2a(oneline))) or last_comment_3f)) then - local function _40_() + local function _41_() if last_comment_3f then return indent_str else return "" end end - return (open .. table.concat(elements, indent_str) .. _40_() .. close) + return (open .. table.concat(elements, indent_str) .. _41_() .. close) else return oneline end @@ -5048,10 +5086,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) if getopt(options, "utf8?") then slength = utf8_len else - local function _43_(_241) + local function _44_(_241) return #_241 end - slength = _43_ + slength = _44_ end local prefix = nil if visible_cycle_3f0 then @@ -5064,10 +5102,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local options0 = normalize_opts(options) local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _46_0 in ipairs(kv) do - local _47_ = _46_0 - local k = _47_[1] - local v = _47_[2] + for _, _47_0 in ipairs(kv) do + local _48_ = _47_0 + local k = _48_[1] + local v = _48_[2] local val_19_ = nil do local k0 = pp(k, options0, (indent0 + 1), true) @@ -5108,10 +5146,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local options0 = normalize_opts(options) local tbl_17_ = {} local i_18_ = #tbl_17_ - for _, _51_0 in ipairs(kv) do - local _52_ = _51_0 - local _0 = _52_[1] - local v = _52_[2] + for _, _52_0 in ipairs(kv) do + local _53_ = _52_0 + local _0 = _53_[1] + local v = _53_[2] local val_19_ = nil do local v0 = pp(v, options0, indent0) @@ -5137,7 +5175,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end else local oneline = nil - local _56_ + local _57_ do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -5148,9 +5186,9 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) tbl_17_[i_18_] = val_19_ end end - _56_ = tbl_17_ + _57_ = tbl_17_ end - oneline = table.concat(_56_, " ") + oneline = table.concat(_57_, " ") if (not getopt(options, "one-line?") and (force_multi_line_3f or oneline:find("\n") or (options["line-length"] < (indent + length_2a(oneline))))) then return table.concat(lines, ("\n" .. string.rep(" ", indent))) else @@ -5167,10 +5205,10 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end else local _ = nil - local function _61_(_241) + local function _62_(_241) return visible_cycle_3f(_241, options) end - options["visible-cycle?"] = _61_ + options["visible-cycle?"] = _62_ _ = nil local lines, force_multi_line_3f = nil, nil do @@ -5178,13 +5216,13 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) lines, force_multi_line_3f = metamethod(t, pp, options0, indent) end options["visible-cycle?"] = nil - local _62_0 = type(lines) - if (_62_0 == "string") then + local _63_0 = type(lines) + if (_63_0 == "string") then return lines - elseif (_62_0 == "table") then + elseif (_63_0 == "table") then return concat_lines(lines, options, indent, force_multi_line_3f) else - local _0 = _62_0 + local _0 = _63_0 return error("__fennelview metamethod must return a table of lines") end end @@ -5193,40 +5231,40 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) options.level = (options.level + 1) local x0 = nil do - local _65_0 = nil + local _66_0 = nil if getopt(options, "metamethod?") then - local _66_0 = x - if (nil ~= _66_0) then - local _67_0 = getmetatable(_66_0) - if (nil ~= _67_0) then - _65_0 = _67_0.__fennelview + local _67_0 = x + if (nil ~= _67_0) then + local _68_0 = getmetatable(_67_0) + if (nil ~= _68_0) then + _66_0 = _68_0.__fennelview else - _65_0 = _67_0 + _66_0 = _68_0 end else - _65_0 = _66_0 + _66_0 = _67_0 end else - _65_0 = nil + _66_0 = nil end - if (nil ~= _65_0) then - local metamethod = _65_0 + if (nil ~= _66_0) then + local metamethod = _66_0 x0 = pp_metamethod(x, metamethod, options, indent) else - local _ = _65_0 - local _71_0, _72_0 = table_kv_pairs(x, options) - if (true and (_72_0 == "empty")) then - local _0 = _71_0 + local _ = _66_0 + local _72_0, _73_0 = table_kv_pairs(x, options) + if (true and (_73_0 == "empty")) then + local _0 = _72_0 if getopt(options, "empty-as-sequence?") then x0 = "[]" else x0 = "{}" end - elseif ((nil ~= _71_0) and (_72_0 == "table")) then - local kv = _71_0 + elseif ((nil ~= _72_0) and (_73_0 == "table")) then + local kv = _72_0 x0 = pp_associative(x, kv, options, indent) - elseif ((nil ~= _71_0) and (_72_0 == "seq")) then - local kv = _71_0 + elseif ((nil ~= _72_0) and (_73_0 == "seq")) then + local kv = _72_0 x0 = pp_sequence(x, kv, options, indent) else x0 = nil @@ -5238,7 +5276,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end local function exponential_notation(n, fallback) local s = nil - for i = 0, 308 do + for i = 0, 99 do if s then break end local s0 = string.format(("%." .. i .. "e"), n) if (n == tonumber(s0)) then @@ -5265,7 +5303,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) val = (options.nan or ".nan") end elseif (math.floor(n) == n) then - local s1 = string.format("%.f", n) + local s1 = string.format("%.0f", n) if (s1 == inf_str) then val = (options.infinity or ".inf") elseif (s1 == neg_inf_str) then @@ -5278,8 +5316,8 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) else val = tostring(n) end - local _81_0 = string.gsub(val, ",", ".") - return _81_0 + local _82_0 = string.gsub(val, ",", ".") + return _82_0 end local function colon_string_3f(s) return s:find("^[-%w?^_!$%&*+./|<=>]+$") @@ -5297,12 +5335,12 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local ret = nil for _, init0 in ipairs(inits) do if ret then break end - ret = (byte and (function(_82_,_83_,_84_) return (_82_ <= _83_) and (_83_ <= _84_) end)(init0["min-byte"],byte,init0["max-byte"]) and init0) + ret = (byte and (function(_83_,_84_,_85_) return (_83_ <= _84_) and (_84_ <= _85_) end)(init0["min-byte"],byte,init0["max-byte"]) and init0) end init = ret end local code = nil - local function _85_() + local function _86_() local code0 = nil if init then code0 = (byte - init["min-byte"]) @@ -5315,8 +5353,8 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end return code0 end - code = (init and _85_()) - if (code and (function(_87_,_88_,_89_) return (_87_ <= _88_) and (_88_ <= _89_) end)(init["min-code"],code,init["max-code"]) and not ((55296 <= code) and (code <= 57343))) then + code = (init and _86_()) + if (code and (function(_88_,_89_,_90_) return (_88_ <= _89_) and (_89_ <= _90_) end)(init["min-code"],code,init["max-code"]) and not ((55296 <= code) and (code <= 57343))) then return init.len end end @@ -5343,16 +5381,16 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) local esc_newline_3f = ((len < 2) or (getopt(options, "escape-newlines?") and (len < (options["line-length"] - indent)))) local byte_escape = (getopt(options, "byte-escape") or default_byte_escape) local escs = nil - local _93_ + local _94_ if esc_newline_3f then - _93_ = "\\n" + _94_ = "\\n" else - _93_ = "\n" + _94_ = "\n" end - local function _95_(_241, _242) + local function _96_(_241, _242) return byte_escape(_242:byte(), options) end - escs = setmetatable({["\""] = "\\\"", ["\11"] = "\\v", ["\12"] = "\\f", ["\13"] = "\\r", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\\"] = "\\\\", ["\n"] = _93_}, {__index = _95_}) + escs = setmetatable({["\""] = "\\\"", ["\11"] = "\\v", ["\12"] = "\\f", ["\13"] = "\\r", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\\"] = "\\\\", ["\n"] = _94_}, {__index = _96_}) local str0 = ("\"" .. str:gsub("[%c\\\"]", escs) .. "\"") if getopt(options, "utf8?") then return utf8_escape(str0, options) @@ -5381,7 +5419,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end return defaults end - local function _98_(x, options, indent, colon_3f) + local function _99_(x, options, indent, colon_3f) local indent0 = (indent or 0) local options0 = (options or make_options(x)) local x0 = nil @@ -5391,19 +5429,19 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) x0 = x end local tv = type(x0) - local function _101_() - local _100_0 = getmetatable(x0) - if ((_G.type(_100_0) == "table") and true) then - local __fennelview = _100_0.__fennelview + local function _102_() + local _101_0 = getmetatable(x0) + if ((_G.type(_101_0) == "table") and true) then + local __fennelview = _101_0.__fennelview return __fennelview end end - if ((tv == "table") or ((tv == "userdata") and _101_())) then + if ((tv == "table") or ((tv == "userdata") and _102_())) then return pp_table(x0, options0, indent0) elseif (tv == "number") then return number__3estring(x0, options0) else - local function _103_() + local function _104_() if (colon_3f ~= nil) then return colon_3f elseif ("function" == type(options0["prefer-colon?"])) then @@ -5412,7 +5450,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) return getopt(options0, "prefer-colon?") end end - if ((tv == "string") and colon_string_3f(x0) and _103_()) then + if ((tv == "string") and colon_string_3f(x0) and _104_()) then return (":" .. x0) elseif (tv == "string") then return pp_string(x0, options0, indent0) @@ -5423,7 +5461,7 @@ package.preload["fennel.view"] = package.preload["fennel.view"] or function(...) end end end - pp = _98_ + pp = _99_ local function _view(x, _3foptions) return pp(x, make_options(x, _3foptions), 0) end @@ -5431,7 +5469,28 @@ 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.5.1" + local version = "1.5.3" + local unpack = (table.unpack or _G.unpack) + local pack = nil + local function _106_(...) + local _107_0 = {...} + _107_0["n"] = select("#", ...) + return _107_0 + end + pack = (table.pack or _106_) + local maxn = nil + local function _108_(_241) + local max = 0 + for k in pairs(_241) do + if (("number" == type(k)) and (max < k)) then + max = k + else + max = max + end + end + return max + end + maxn = (table.maxn or _108_) 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 @@ -5468,32 +5527,32 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local len = nil do - local _108_0, _109_0 = pcall(require, "utf8") - if ((_108_0 == true) and (nil ~= _109_0)) then - local utf8 = _109_0 + local _113_0, _114_0 = pcall(require, "utf8") + if ((_113_0 == true) and (nil ~= _114_0)) then + local utf8 = _114_0 len = utf8.len else - local _ = _108_0 + local _ = _113_0 len = string.len end end local kv_order = {boolean = 2, number = 1, string = 3, table = 4} local function kv_compare(a, b) - local _111_0, _112_0 = type(a), type(b) - if (((_111_0 == "number") and (_112_0 == "number")) or ((_111_0 == "string") and (_112_0 == "string"))) then + local _116_0, _117_0 = type(a), type(b) + if (((_116_0 == "number") and (_117_0 == "number")) or ((_116_0 == "string") and (_117_0 == "string"))) then return (a < b) else - local function _113_() - local a_t = _111_0 - local b_t = _112_0 + local function _118_() + local a_t = _116_0 + local b_t = _117_0 return (a_t ~= b_t) end - if (((nil ~= _111_0) and (nil ~= _112_0)) and _113_()) then - local a_t = _111_0 - local b_t = _112_0 + if (((nil ~= _116_0) and (nil ~= _117_0)) and _118_()) then + local a_t = _116_0 + local b_t = _117_0 return ((kv_order[a_t] or 5) < (kv_order[b_t] or 5)) else - local _ = _111_0 + local _ = _116_0 return (tostring(a) < tostring(b)) end end @@ -5525,20 +5584,20 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. local function stablepairs(t) local mt_keys = nil do - local _117_0 = getmetatable(t) - if (nil ~= _117_0) then - _117_0 = _117_0.keys + local _122_0 = getmetatable(t) + if (nil ~= _122_0) then + _122_0 = _122_0.keys end - mt_keys = _117_0 + mt_keys = _122_0 end local succ, prev, first_mt = nil, nil, nil - local function _119_(_241) + local function _124_(_241) return t[_241] end - succ, prev, first_mt = add_stable_keys({}, nil, (mt_keys or {}), _119_) + succ, prev, first_mt = add_stable_keys({}, nil, (mt_keys or {}), _124_) local pairs_keys = nil do - local _120_0 = nil + local _125_0 = nil do local tbl_17_ = {} local i_18_ = #tbl_17_ @@ -5549,10 +5608,10 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_17_[i_18_] = val_19_ end end - _120_0 = tbl_17_ + _125_0 = tbl_17_ end - table.sort(_120_0, kv_compare) - pairs_keys = _120_0 + table.sort(_125_0, kv_compare) + pairs_keys = _125_0 end local succ0, _, first_after_mt = add_stable_keys(succ, prev, pairs_keys) local first = nil @@ -5562,19 +5621,19 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. first = first_mt end local function stablenext(tbl, key) - local _123_0 = nil + local _128_0 = nil if (key == nil) then - _123_0 = first + _128_0 = first else - _123_0 = succ0[key] + _128_0 = succ0[key] end - if (nil ~= _123_0) then - local next_key = _123_0 - local _125_0 = tbl[next_key] - if (_125_0 ~= nil) then - return next_key, _125_0 + if (nil ~= _128_0) then + local next_key = _128_0 + local _130_0 = tbl[next_key] + if (_130_0 ~= nil) then + return next_key, _130_0 else - return _125_0 + return _130_0 end end end @@ -5605,27 +5664,16 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return tbl_14_ end local function member_3f(x, tbl, _3fn) - local _131_0 = tbl[(_3fn or 1)] - if (_131_0 == x) then + local _136_0 = tbl[(_3fn or 1)] + if (_136_0 == x) then return true - elseif (_131_0 == nil) then + elseif (_136_0 == nil) then return nil else - local _ = _131_0 + local _ = _136_0 return member_3f(x, tbl, ((_3fn or 1) + 1)) end end - local function maxn(tbl) - local max = 0 - for k in pairs(tbl) do - if ("number" == type(k)) then - max = math.max(max, k) - else - max = max - end - end - return max - end local function every_3f(t, predicate) local result = true for _, item in ipairs(t) do @@ -5646,9 +5694,9 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. seen[next_state] = true return next_state, value else - local _134_0 = getmetatable(t) - if ((_G.type(_134_0) == "table") and true) then - local __index = _134_0.__index + local _138_0 = getmetatable(t) + if ((_G.type(_138_0) == "table") and true) then + local __index = _138_0.__index if ("table" == type(__index)) then t = __index return allpairs_next(t) @@ -5682,9 +5730,6 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return ("(" .. table.concat(viewed, " ") .. ")") end - local function comment_view(c) - return c, true - end local function sym_3d(a, b) return ((deref(a) == deref(b)) and (getmetatable(a) == getmetatable(b))) end @@ -5693,19 +5738,23 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local symbol_mt = {"SYMBOL", __eq = sym_3d, __fennelview = deref, __lt = sym_3c, __tostring = deref} local expr_mt = nil - local function _140_(x) + local function _144_(x) return tostring(deref(x)) end - expr_mt = {"EXPR", __tostring = _140_} + expr_mt = {"EXPR", __tostring = _144_} local list_mt = {"LIST", __fennelview = list__3estring, __tostring = list__3estring} - local comment_mt = {"COMMENT", __eq = sym_3d, __fennelview = comment_view, __lt = sym_3c, __tostring = deref} + local comment_mt = nil + local function _145_(_241) + return _241 + end + comment_mt = {"COMMENT", __eq = sym_3d, __fennelview = _145_, __lt = sym_3c, __tostring = deref} local sequence_marker = {"SEQUENCE"} local varg_mt = {"VARARG", __fennelview = deref, __tostring = deref} local getenv = nil - local function _141_() + local function _146_() return nil end - getenv = ((os and os.getenv) or _141_) + getenv = ((os and os.getenv) or _146_) local function debug_on_3f(flag) local level = (getenv("FENNEL_DEBUG") or "") return ((level == "all") or level:find(flag)) @@ -5714,7 +5763,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return setmetatable({...}, list_mt) end local function sym(str, _3fsource) - local _142_ + local _147_ do local tbl_14_ = {str} for k, v in pairs((_3fsource or {})) do @@ -5728,12 +5777,12 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_14_[k_15_] = v_16_ end end - _142_ = tbl_14_ + _147_ = tbl_14_ end - return setmetatable(_142_, symbol_mt) + return setmetatable(_147_, symbol_mt) end local function sequence(...) - local function _145_(seq, view0, inspector, indent) + local function _150_(seq, view0, inspector, indent) local opts = nil do inspector["empty-as-sequence?"] = {after = inspector["empty-as-sequence?"], once = true} @@ -5742,19 +5791,19 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return view0(seq, opts, indent) end - return setmetatable({...}, {__fennelview = _145_, sequence = sequence_marker}) + return setmetatable({...}, {__fennelview = _150_, sequence = sequence_marker}) end local function expr(strcode, etype) return setmetatable({strcode, type = etype}, expr_mt) end local function comment_2a(contents, _3fsource) - local _146_ = (_3fsource or {}) - local filename = _146_["filename"] - local line = _146_["line"] + local _151_ = (_3fsource or {}) + local filename = _151_["filename"] + local line = _151_["line"] return setmetatable({contents, filename = filename, line = line}, comment_mt) end local function varg(_3fsource) - local _147_ + local _152_ do local tbl_14_ = {"..."} for k, v in pairs((_3fsource or {})) do @@ -5768,9 +5817,9 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. tbl_14_[k_15_] = v_16_ end end - _147_ = tbl_14_ + _152_ = tbl_14_ end - return setmetatable(_147_, varg_mt) + return setmetatable(_152_, varg_mt) end local function expr_3f(x) return ((type(x) == "table") and (getmetatable(x) == expr_mt) and x) @@ -5820,7 +5869,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. elseif (type(str) ~= "string") then return false else - local function _153_() + local function _158_() local parts = {} for part in str:gmatch("[^%.%:]+[%.%:]?") do local last_char = part:sub(-1) @@ -5835,7 +5884,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end return (next(parts) and parts) end - return ((str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte() ~= string.byte(":")) and (str:byte(-1) ~= string.byte(".")) and (str:byte(-1) ~= string.byte(":")) and _153_()) + return ((str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte() ~= string.byte(":")) and (str:byte(-1) ~= string.byte(".")) and (str:byte(-1) ~= string.byte(":")) and _158_()) end end local function call_of_3f(ast, callee) @@ -5861,15 +5910,15 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. return root end local root = nil - local function _158_() + local function _163_() end - root = {chunk = nil, options = nil, reset = _158_, scope = nil} - root["set-reset"] = function(_159_0) - local _160_ = _159_0 - local chunk = _160_["chunk"] - local options = _160_["options"] - local reset = _160_["reset"] - local scope = _160_["scope"] + root = {chunk = nil, options = nil, reset = _163_, scope = nil} + root["set-reset"] = function(_164_0) + local _165_ = _164_0 + local chunk = _165_["chunk"] + local options = _165_["options"] + local reset = _165_["reset"] + local scope = _165_["scope"] root.reset = function() root.chunk, root.scope, root.options, root.reset = chunk, scope, options, reset return nil @@ -5878,17 +5927,17 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local lua_keywords = {["and"] = true, ["break"] = true, ["do"] = true, ["else"] = true, ["elseif"] = true, ["end"] = true, ["false"] = true, ["for"] = true, ["function"] = true, ["goto"] = true, ["if"] = true, ["in"] = true, ["local"] = true, ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true, ["return"] = true, ["then"] = true, ["true"] = true, ["until"] = true, ["while"] = true} local function lua_keyword_3f(str) - local function _162_() - local _161_0 = root.options - if (nil ~= _161_0) then - _161_0 = _161_0.keywords + local function _167_() + local _166_0 = root.options + if (nil ~= _166_0) then + _166_0 = _166_0.keywords end - if (nil ~= _161_0) then - _161_0 = _161_0[str] + if (nil ~= _166_0) then + _166_0 = _166_0[str] end - return _161_0 + return _166_0 end - return (lua_keywords[str] or _162_()) + return (lua_keywords[str] or _167_()) end local function valid_lua_identifier_3f(str) return (str:match("^[%a_][%w_]*$") and not lua_keyword_3f(str)) @@ -5914,29 +5963,29 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end end local function warn(msg, _3fast, _3ffilename, _3fline) - local _167_0 = nil + local _172_0 = nil do - local _168_0 = root.options - if (nil ~= _168_0) then - _168_0 = _168_0.warn + local _173_0 = root.options + if (nil ~= _173_0) then + _173_0 = _173_0.warn end - _167_0 = _168_0 + _172_0 = _173_0 end - if (nil ~= _167_0) then - local opt_warn = _167_0 + if (nil ~= _172_0) then + local opt_warn = _172_0 return opt_warn(msg, _3fast, _3ffilename, _3fline) else - local _ = _167_0 + local _ = _172_0 if (_G.io and _G.io.stderr) then local loc = nil do - local _170_0 = ast_source(_3fast) - if ((_G.type(_170_0) == "table") and (nil ~= _170_0.filename) and (nil ~= _170_0.line)) then - local filename = _170_0.filename - local line = _170_0.line + local _175_0 = ast_source(_3fast) + if ((_G.type(_175_0) == "table") and (nil ~= _175_0.filename) and (nil ~= _175_0.line)) then + local filename = _175_0.filename + local line = _175_0.line loc = (filename .. ":" .. line .. ": ") else - local _0 = _170_0 + local _0 = _175_0 if (_3ffilename and _3fline) then loc = (_3ffilename .. ":" .. _3fline .. ": ") else @@ -5949,11 +5998,11 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end end local warned = {} - local function check_plugin_version(_175_0) - local _176_ = _175_0 - local plugin = _176_ - local name = _176_["name"] - local versions = _176_["versions"] + local function check_plugin_version(_180_0) + local _181_ = _180_0 + local plugin = _181_ + local name = _181_["name"] + local versions = _181_["versions"] if (not member_3f(version:gsub("-dev", ""), (versions or {})) and not (string_3f(versions) and version:find(versions)) and not warned[plugin]) then warned[plugin] = true return warn(string.format("plugin %s does not support Fennel version %s", (name or "unknown"), version)) @@ -5961,29 +6010,29 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. end local function hook_opts(event, _3foptions, ...) local plugins = nil - local function _179_(...) - local _178_0 = _3foptions - if (nil ~= _178_0) then - _178_0 = _178_0.plugins + local function _184_(...) + local _183_0 = _3foptions + if (nil ~= _183_0) then + _183_0 = _183_0.plugins end - return _178_0 + return _183_0 end - local function _182_(...) - local _181_0 = root.options - if (nil ~= _181_0) then - _181_0 = _181_0.plugins + local function _187_(...) + local _186_0 = root.options + if (nil ~= _186_0) then + _186_0 = _186_0.plugins end - return _181_0 + return _186_0 end - plugins = (_179_(...) or _182_(...)) + plugins = (_184_(...) or _187_(...)) if plugins then local result = nil for _, plugin in ipairs(plugins) do if (nil ~= result) then break end check_plugin_version(plugin) - local _184_0 = plugin[event] - if (nil ~= _184_0) then - local f = _184_0 + local _189_0 = plugin[event] + if (nil ~= _189_0) then + local f = _189_0 result = f(...) else result = nil @@ -5995,7 +6044,7 @@ package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(.. local function hook(event, ...) return hook_opts(event, root.options, ...) end - return {["ast-source"] = ast_source, ["call-of?"] = call_of_3f, ["comment?"] = comment_3f, ["debug-on?"] = debug_on_3f, ["every?"] = every_3f, ["expr?"] = expr_3f, ["fennel-module"] = nil, ["get-in"] = get_in, ["hook-opts"] = hook_opts, ["idempotent-expr?"] = idempotent_expr_3f, ["kv-table?"] = kv_table_3f, ["list?"] = list_3f, ["lua-keyword?"] = lua_keyword_3f, ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";"), ["member?"] = member_3f, ["multi-sym?"] = multi_sym_3f, ["propagate-options"] = propagate_options, ["quoted?"] = quoted_3f, ["runtime-version"] = runtime_version, ["sequence?"] = sequence_3f, ["string?"] = string_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["varg?"] = varg_3f, ["walk-tree"] = walk_tree, allpairs = allpairs, comment = comment_2a, copy = copy, expr = expr, hook = hook, len = len, list = list, maxn = maxn, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), root = root, sequence = sequence, stablepairs = stablepairs, sym = sym, varg = varg, version = version, warn = warn} + return {["ast-source"] = ast_source, ["call-of?"] = call_of_3f, ["comment?"] = comment_3f, ["debug-on?"] = debug_on_3f, ["every?"] = every_3f, ["expr?"] = expr_3f, ["fennel-module"] = nil, ["get-in"] = get_in, ["hook-opts"] = hook_opts, ["idempotent-expr?"] = idempotent_expr_3f, ["kv-table?"] = kv_table_3f, ["list?"] = list_3f, ["lua-keyword?"] = lua_keyword_3f, ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";"), ["member?"] = member_3f, ["multi-sym?"] = multi_sym_3f, ["propagate-options"] = propagate_options, ["quoted?"] = quoted_3f, ["runtime-version"] = runtime_version, ["sequence?"] = sequence_3f, ["string?"] = string_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["varg?"] = varg_3f, ["walk-tree"] = walk_tree, allpairs = allpairs, comment = comment_2a, copy = copy, expr = expr, hook = hook, len = len, list = list, maxn = maxn, pack = pack, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), root = root, sequence = sequence, stablepairs = stablepairs, sym = sym, unpack = unpack, varg = varg, version = version, warn = warn} end package.preload["fennel"] = package.preload["fennel"] or function(...) local utils = require("fennel.utils") @@ -6033,14 +6082,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 _841_(...) + local function _858_(...) if opts.filename then return ("@" .. opts.filename) else return str end end - loader = specials["load-code"](lua_source, env, _841_(...)) + loader = specials["load-code"](lua_source, env, _858_(...)) opts.filename = nil return loader(...) end @@ -6066,10 +6115,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 _842_0 = type(v) - if (_842_0 == "function") then + local _859_0 = type(v) + if (_859_0 == "function") then out[k] = {["function?"] = true, ["global?"] = true} - elseif (_842_0 == "table") then + elseif (_859_0 == "table") then if not k:find("^_") then for k2, v2 in pairs(v) do if ("function" == type(v2)) then @@ -6088,863 +6137,859 @@ package.preload["fennel"] = package.preload["fennel"] or function(...) return mod end utils["fennel-module"] = mod + local function load_macros(src, env) + local chunk = assert(specials["load-code"](src, env, "src/fennel/macros.fnl")) + for k, v in pairs(chunk()) do + compiler.scopes.global.macros[k] = v + end + return nil + end do - local module_name = "fennel.macros" - local _ = nil - local function _846_() - return mod + local env = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) + env.utils = utils + env["get-function-metadata"] = specials["get-function-metadata"] + load_macros([===[local function copy(t) + local out = {} + for _, v in ipairs(t) do + table.insert(out, v) + end + return setmetatable(out, getmetatable(t)) end - package.preload[module_name] = _846_ - _ = nil - local env = nil - do - local _847_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}) - _847_0["utils"] = utils - _847_0["fennel"] = mod - _847_0["get-function-metadata"] = specials["get-function-metadata"] - env = _847_0 + utils['fennel-module'].metadata:setall(copy, "fnl/arglist", {"t"}) + local function __3e_2a(val, ...) + local x = val + for _, e in ipairs({...}) do + local elt = nil + if _G["list?"](e) then + elt = copy(e) + else + elt = list(e) + end + table.insert(elt, 2, x) + x = elt + end + return x end - 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] - (let [out []] - (each [_ v (ipairs t)] (table.insert out v)) - (setmetatable out (getmetatable t)))) - - (fn ->* [val ...] - "Thread-first macro. - Take the first value and splice it into the second form as its first argument. - The value of the second form is spliced into the first arg of the third, etc." - (var x val) - (each [_ e (ipairs [...])] - (let [elt (if (list? e) (copy e) (list e))] - (table.insert elt 2 x) - (set x elt))) - x) - - (fn ->>* [val ...] - "Thread-last macro. - Same as ->, except splices the value into the last position of each form - rather than the first." - (var x val) - (each [_ e (ipairs [...])] - (let [elt (if (list? e) (copy e) (list e))] - (table.insert elt x) - (set x elt))) - x) - - (fn -?>* [val ?e ...] - "Nil-safe thread-first macro. - Same as -> except will short-circuit with nil when it encounters a nil value." - (if (= nil ?e) - val - (not (utils.idempotent-expr? val)) - ;; try again, but with an eval-safe val - `(let [tmp# ,val] - (-?> tmp# ,?e ,...)) - (let [call (if (list? ?e) (copy ?e) (list ?e))] - (table.insert call 2 val) - `(if (not= nil ,val) - ,(-?>* call ...))))) - - (fn -?>>* [val ?e ...] - "Nil-safe thread-last macro. - Same as ->> except will short-circuit with nil when it encounters a nil value." - (if (= nil ?e) - val - (not (utils.idempotent-expr? val)) - ;; try again, but with an eval-safe val - `(let [tmp# ,val] - (-?>> tmp# ,?e ,...)) - (let [call (if (list? ?e) (copy ?e) (list ?e))] - (table.insert call val) - `(if (not= ,val nil) - ,(-?>>* call ...))))) - - (fn ?dot [tbl ...] - "Nil-safe table look up. - Same as . (dot), except will short-circuit with nil when it encounters - a nil value in any of subsequent keys." - (let [head (gensym :t) - lookups `(do - (var ,head ,tbl) - ,head)] - (each [i k (ipairs [...])] - ;; Kinda gnarly to reassign in place like this, but it emits the best lua. - ;; With this impl, it emits a flat, concise, and readable set of ifs - (table.insert lookups (+ i 2) - `(if (not= nil ,head) (set ,head (. ,head ,k))))) - lookups)) - - (fn doto* [val ...] - "Evaluate val and splice it into the first argument of subsequent forms." - (assert (not= val nil) "missing subject") - (if (not (utils.idempotent-expr? val)) - `(let [tmp# ,val] - (doto tmp# ,...)) - (let [form `(do)] - (each [_ elt (ipairs [...])] - (let [elt (if (list? elt) (copy elt) (list elt))] - (table.insert elt 2 val) - (table.insert form elt))) - (table.insert form val) - form))) - - (fn when* [condition body1 ...] - "Evaluate body for side-effects only when condition is truthy." - (assert body1 "expected body") - `(if ,condition - (do - ,body1 - ,...))) - - (fn with-open* [closable-bindings ...] - "Like `let`, but invokes (v:close) on each binding after evaluating the body. - The body is evaluated inside `xpcall` so that bound values will be closed upon - encountering an error before propagating it." - (let [bodyfn `(fn [] - ,...) - closer `(fn close-handlers# [ok# ...] - (if ok# ... (error ... 0))) - traceback `(. (or (. package.loaded ,(fennel-module-name)) _G.debug {}) - :traceback)] - (for [i 1 (length closable-bindings) 2] - (assert (sym? (. closable-bindings i)) - "with-open only allows symbols in bindings") - (table.insert closer 4 `(: ,(. closable-bindings i) :close))) - `(let ,closable-bindings - ,closer - (close-handlers# (_G.xpcall ,bodyfn ,traceback))))) - - (fn extract-into [iter-tbl] - (var (into iter-out found?) (values [] (copy iter-tbl))) - (for [i (length iter-tbl) 2 -1] - (let [item (. iter-tbl i)] - (if (or (sym? item "&into") (= :into item)) - (do - (assert (not found?) "expected only one &into clause") - (set found? true) - (set into (. iter-tbl (+ i 1))) - (table.remove iter-out i) - (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 found?)) - - (fn collect* [iter-tbl key-expr value-expr ...] - "Return a table made by running an iterator and evaluating an expression that - returns key-value pairs to be inserted sequentially into the table. This can - be thought of as a table comprehension. The body should provide two expressions - (used as key and value) or nil, which causes it to be omitted. - - For example, - (collect [k v (pairs {:apple \"red\" :orange \"orange\"})] - (values v k)) - returns - {:red \"apple\" :orange \"orange\"} - - Supports an &into clause after the iterator to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl))) - "expected iterator binding table") - (assert (not= nil key-expr) "expected key and value expression") - (assert (= nil ...) - "expected 1 or 2 body expressions; wrap multiple expressions with do") - (assert (or value-expr (list? key-expr)) "need key and value") - (let [kv-expr (if (= nil value-expr) key-expr `(values ,key-expr ,value-expr)) - (into iter) (extract-into iter-tbl)] - `(let [tbl# ,into] - (each ,iter - (let [(k# v#) ,kv-expr] - (if (and (not= k# nil) (not= v# nil)) - (tset tbl# k# v#)))) - tbl#))) - - (fn seq-collect [how iter-tbl value-expr ...] - "Common part between icollect and fcollect for producing sequential tables. - - Iteration code only differs in using the for or each keyword, the rest - of the generated code is identical." - (assert (not= nil value-expr) "expected table value expression") - (assert (= nil ...) - "expected exactly one body expression. Wrap multiple expressions in do") - (let [(into iter has-into?) (extract-into iter-tbl)] - (if has-into? - `(let [tbl# ,into] - (,how ,iter (let [val# ,value-expr] - (table.insert tbl# val#))) - 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 - expression that returns values to be inserted sequentially into the table. - This can be thought of as a table comprehension. If the body evaluates to nil - that element is omitted. - - For example, - (icollect [_ v (ipairs [1 2 3 4 5])] - (when (not= v 3) - (* v v))) - returns - [1 4 16 25] - - Supports an &into clause after the iterator to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl))) - "expected iterator binding table") - (seq-collect 'each iter-tbl value-expr ...)) - - (fn fcollect* [iter-tbl value-expr ...] - "Return a sequential table made by advancing a range as specified by - for, and evaluating an expression that returns values to be inserted - sequentially into the table. This can be thought of as a range - comprehension. If the body evaluates to nil that element is omitted. - - For example, - (fcollect [i 1 10 2] - (when (not= i 3) - (* i i))) - returns - [1 25 49 81] - - Supports an &into clause after the range to put results in an existing table. - Supports early termination with an &until clause." - (assert (and (sequence? iter-tbl) (< 2 (length iter-tbl))) - "expected range binding table") - (seq-collect 'for iter-tbl value-expr ...)) - - (fn accumulate-impl [for? iter-tbl body ...] - (assert (and (sequence? iter-tbl) (<= 4 (length iter-tbl))) - "expected initial value and iterator binding table") - (assert (not= nil body) "expected body expression") - (assert (= nil ...) - "expected exactly one body expression. Wrap multiple expressions with do") - (let [[accum-var accum-init] iter-tbl - iter (sym (if for? "for" "each"))] ; accumulate or faccumulate? - `(do - (var ,accum-var ,accum-init) - (,iter ,[(unpack iter-tbl 3)] - (set ,accum-var ,body)) - ,(if (list? accum-var) - (list (sym :values) (unpack accum-var)) - accum-var)))) - - (fn accumulate* [iter-tbl body ...] - "Accumulation macro. - - It takes a binding table and an expression as its arguments. In the binding - table, the first form starts out bound to the second value, which is an initial - accumulator. The rest are an iterator binding table in the format `each` takes. - - It runs through the iterator in each step of which the given expression is - evaluated, and the accumulator is set to the value of the expression. It - eventually returns the final value of the accumulator. - - For example, - (accumulate [total 0 - _ n (pairs {:apple 2 :orange 3})] - (+ total n)) - returns 5" - (accumulate-impl false iter-tbl body ...)) - - (fn faccumulate* [iter-tbl body ...] - "Identical to accumulate, but after the accumulator the binding table is the - same as `for` instead of `each`. Like collect to fcollect, will iterate over a - numerical range like `for` rather than an iterator." - (accumulate-impl true iter-tbl body ...)) - - (fn partial* [f ...] - "Return a function with all arguments partially applied to f." - (assert f "expected a function to partially apply") - (let [bindings [] - args []] - (each [_ arg (ipairs [...])] - (if (utils.idempotent-expr? arg) - (table.insert args arg) - (let [name (gensym)] - (table.insert bindings name) - (table.insert bindings arg) - (table.insert args name)))) - (let [body (list f (unpack args))] - (table.insert body _VARARG) - ;; only use the extra let if we need double-eval protection - (if (= nil (. bindings 1)) - `(fn [,_VARARG] ,body) - `(let ,bindings - (fn [,_VARARG] ,body)))))) - - (fn pick-args* [n f] - "Create a function of arity n that applies its arguments to f. Deprecated." - (if (and _G.io _G.io.stderr) - (_G.io.stderr:write - "-- WARNING: pick-args is deprecated and will be removed in the future.\n")) - (let [bindings []] - (for [i 1 n] (tset bindings i (gensym))) - `(fn ,bindings (,f ,(unpack bindings))))) - - (fn lambda* [...] - "Function literal with nil-checked arguments. - Like `fn`, but will throw an exception if a declared argument is passed in as - nil, unless that argument's name begins with a question mark." - (let [args [...] - args-len (length args) - has-internal-name? (sym? (. args 1)) - arglist (if has-internal-name? (. args 2) (. args 1)) - metadata-position (if has-internal-name? 3 2) - (_ check-position) (get-function-metadata [:lambda ...] arglist - metadata-position) - empty-body? (< args-len check-position)] - (fn check! [a] - (if (table? a) - (each [_ a (pairs a)] (check! a)) - (let [as (tostring a)] - (and (not (as:find "^?")) (not= as "&") (not (as:find "^_")) - (not= as "...") (not= as "&as"))) - (table.insert args check-position - `(_G.assert (not= nil ,a) - ,(: "Missing argument %s on %s:%s" :format - (tostring a) - (or a.filename :unknown) - (or a.line "?")))))) - - (assert (= :table (type arglist)) "expected arg list") - (each [_ a (ipairs arglist)] (check! a)) - (if empty-body? (table.insert args (sym :nil))) - `(fn ,(unpack args)))) - - (fn macro* [name ...] - "Define a single macro." - (assert (sym? name) "expected symbol for macro name") - (local args [...]) - `(macros {,(tostring name) (fn ,(unpack args))})) - - (fn macrodebug* [form return?] - "Print the resulting form after performing macroexpansion. - With a second argument, returns expanded form as a string instead of printing." - (let [handle (if return? `do `print)] - ;; TODO: Provide a helpful compiler error in the unlikely edge case of an - ;; infinite AST instead of the current "silently expand until max depth" - `(,handle ,(view (macroexpand form _SCOPE) {:detect-cycles? false})))) - - (fn import-macros* [binding1 module-name1 ...] - "Bind a table of macros from each macro module according to a binding form. - Each binding form can be either a symbol or a k/v destructuring table. - Example: - (import-macros mymacros :my-macros ; bind to symbol - {:macro1 alias : macro2} :proj.macros) ; import by name" - (assert (and binding1 module-name1 (= 0 (% (select "#" ...) 2))) - "expected even number of binding/modulename pairs") - (for [i 1 (select "#" binding1 module-name1 ...) 2] - ;; delegate the actual loading of the macros to the require-macros - ;; special which already knows how to set up the compiler env and stuff. - ;; this is weird because require-macros is deprecated but it works. - (let [(binding modname) (select i binding1 module-name1 ...) - scope (get-scope) - ;; if the module-name is an expression (and not just a string) we - ;; patch our expression to have the correct source filename so - ;; require-macros can pass it down when resolving the module-name. - expr `(import-macros ,modname) - filename (if (list? modname) (. modname 1 :filename) :unknown) - _ (tset expr :filename filename) - macros* (_SPECIALS.require-macros expr scope {} binding)] - (if (sym? binding) - ;; bind whole table of macros to table bound to symbol - (tset scope.macros (. binding 1) macros*) - ;; 1-level table destructuring for importing individual macros - (table? binding) - (each [macro-name [import-key] (pairs binding)] - (assert (= :function (type (. macros* macro-name))) - (.. "macro " macro-name " not found in module " - (tostring modname))) - (tset scope.macros import-key (. macros* macro-name)))))) - nil) - - (fn assert-repl* [condition ...] - "Enter into a debug REPL and print the message when condition is false/nil. - Works as a drop-in replacement for Lua's `assert`. - REPL `,return` command returns values to assert in place to continue execution." - {:fnl/arglist [condition ?message ...]} - (fn add-locals [{: symmeta : parent} locals] - (each [name (pairs symmeta)] - (tset locals name (sym name))) - (if parent (add-locals parent locals) locals)) - `(let [unpack# (or table.unpack _G.unpack) - pack# (or table.pack #(doto [$...] (tset :n (select :# $...)))) - ;; need to pack/unpack input args to account for (assert (foo)), - ;; because assert returns *all* arguments upon success - vals# (pack# ,condition ,...) - condition# (. vals# 1) - message# (or (. vals# 2) "assertion failed, entering repl.")] - (if (not condition#) - (let [opts# {:assert-repl? true} - fennel# (require ,(fennel-module-name)) - 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#))) - (values (unpack# vals# 1 vals#.n))))) - - {:-> ->* - :->> ->>* - :-?> -?>* - :-?>> -?>>* - :?. ?dot - :doto doto* - :when when* - :with-open with-open* - :collect collect* - :icollect icollect* - :fcollect fcollect* - :accumulate accumulate* - :faccumulate faccumulate* - :partial partial* - :lambda lambda* - :λ lambda* - :pick-args pick-args* - :macro macro* - :macrodebug macrodebug* - :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 + utils['fennel-module'].metadata:setall(__3e_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Thread-first macro.\nTake the first value and splice it into the second form as its first argument.\nThe value of the second form is spliced into the first arg of the third, etc.") + local function __3e_3e_2a(val, ...) + local x = val + for _, e in ipairs({...}) do + local elt = nil + if _G["list?"](e) then + elt = copy(e) + else + elt = list(e) + end + table.insert(elt, x) + x = elt + end + return x end - _0 = nil - 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. - - (fn copy [t] (collect [k v (pairs t)] k v)) - - (fn double-eval-safe? [x type] - (or (= :number type) (= :string type) (= :boolean type) - (and (sym? x) (not (multi-sym? x))))) - - (fn with [opts k] - (doto (copy opts) (tset k true))) - - (fn without [opts k] - (doto (copy opts) (tset k nil))) - - (fn case-values [vals pattern unifications case-pattern opts] - (let [condition `(and) - bindings []] - (each [i pat (ipairs pattern)] - (let [(subcondition subbindings) (case-pattern [(. vals i)] pat - unifications (without opts :multival?))] - (table.insert condition subcondition) - (icollect [_ b (ipairs subbindings) &into bindings] b))) - (values condition bindings))) - - (fn case-table [val pattern unifications case-pattern opts ?top] - (let [condition (if (= :table ?top) `(and) `(and (= (_G.type ,val) :table))) - bindings []] - (each [k pat (pairs pattern)] - (if (sym? pat :&) - (let [rest-pat (. pattern (+ k 1)) - rest-val `(select ,k ((or table.unpack _G.unpack) ,val)) - subcondition (case-table `(pick-values 1 ,rest-val) - rest-pat unifications case-pattern - (without opts :multival?))] - (if (not (sym? rest-pat)) - (table.insert condition subcondition)) - (assert (= nil (. pattern (+ k 2))) - "expected & rest argument before last parameter") - (table.insert bindings rest-pat) - (table.insert bindings [rest-val])) - (sym? k :&as) - (do - (table.insert bindings pat) - (table.insert bindings val)) - (and (= :number (type k)) (sym? pat :&as)) - (do - (assert (= nil (. pattern (+ k 2))) - "expected &as argument before last parameter") - (table.insert bindings (. pattern (+ k 1))) - (table.insert bindings val)) - ;; don't process the pattern right after &/&as; already got it - (or (not= :number (type k)) (and (not (sym? (. pattern (- k 1)) :&as)) - (not (sym? (. pattern (- k 1)) :&)))) - (let [subval `(. ,val ,k) - (subcondition subbindings) (case-pattern [subval] pat - unifications - (without opts :multival?))] - (table.insert condition subcondition) - (icollect [_ b (ipairs subbindings) &into bindings] b)))) - (values condition bindings))) - - (fn case-guard [vals condition guards unifications case-pattern opts] - (if (. guards 1) - (let [(pcondition bindings) (case-pattern vals condition unifications opts) - condition `(and ,(unpack guards))] - (values `(and ,pcondition - (let ,bindings - ,condition)) bindings)) - (case-pattern vals condition unifications opts))) - - (fn symbols-in-pattern [pattern] - "gives the set of symbols inside a pattern" - (if (list? pattern) - (if (or (sym? (. pattern 1) :where) - (sym? (. pattern 1) :=)) - (symbols-in-pattern (. pattern 2)) - (sym? (. pattern 2) :?) - (symbols-in-pattern (. pattern 1)) - (let [result {}] - (each [_ child-pattern (ipairs pattern)] - (collect [name symbol (pairs (symbols-in-pattern child-pattern)) &into result] - name symbol)) - result)) - (sym? pattern) - (if (and (not (sym? pattern :or)) - (not (sym? pattern :nil))) - {(tostring pattern) pattern} - {}) - (= (type pattern) :table) - (let [result {}] - (each [key-pattern value-pattern (pairs pattern)] - (collect [name symbol (pairs (symbols-in-pattern key-pattern)) &into result] - name symbol) - (collect [name symbol (pairs (symbols-in-pattern value-pattern)) &into result] - name symbol)) - result) - {})) - - (fn symbols-in-every-pattern [pattern-list infer-unification?] - "gives a list of symbols that are present in every pattern in the list" - (let [?symbols (accumulate [?symbols nil - _ pattern (ipairs pattern-list)] - (let [in-pattern (symbols-in-pattern pattern)] - (if ?symbols - (do - (each [name (pairs ?symbols)] - (when (not (. in-pattern name)) - (tset ?symbols name nil))) - ?symbols) - in-pattern)))] - (icollect [_ symbol (pairs (or ?symbols {}))] - (if (not (and infer-unification? - (in-scope? symbol))) - symbol)))) - - (fn case-or [vals pattern guards unifications case-pattern opts] - (let [pattern [(unpack pattern 2)] - bindings (symbols-in-every-pattern pattern opts.infer-unification?)] - (if (= nil (. bindings 1)) - ;; no bindings special case generates simple code - (let [condition (icollect [_ subpattern (ipairs pattern) &into `(or)] - (case-pattern vals subpattern unifications opts))] - (values (if (. guards 1) - `(and ,condition ,(unpack guards)) - condition) - [])) - ;; case with bindings is handled specially, and returns three values instead of two - (let [matched? (gensym :matched?) - bindings-mangled (icollect [_ binding (ipairs bindings)] - (gensym (tostring binding))) - pre-bindings `(if)] - (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 - (values true ,(unpack bindings)))))) - (values matched? - [`(,(unpack bindings)) `(values ,(unpack bindings-mangled))] - [`(,matched? ,(unpack bindings-mangled)) pre-bindings]))))) - - (fn case-pattern [vals pattern unifications opts ?top] - "Take the AST of values and a single pattern and returns a condition - to determine if it matches as well as a list of bindings to - introduce for the duration of the body if it does match." - - ;; This function returns the following values (multival): - ;; a "condition", which is an expression that determines whether the - ;; pattern should match, - ;; a "bindings", which bind all of the symbols used in a pattern - ;; an optional "pre-bindings", which is a list of bindings that happen - ;; before the condition and bindings are evaluated. These should only - ;; come from a (case-or). In this case there should be no recursion: - ;; the call stack should be case-condition > case-pattern > case-or - ;; - ;; Here are the expected flags in the opts table: - ;; :infer-unification? boolean - if the pattern should guess when to unify (ie, match -> true, case -> false) - ;; :multival? boolean - if the pattern can contain multivals (in order to disallow patterns like [(1 2)]) - ;; :in-where? boolean - if the pattern is surrounded by (where) (where opts into more pattern features) - ;; :legacy-guard-allowed? boolean - if the pattern should allow `(a ? b) patterns - - ;; we have to assume we're matching against multiple values here until we - ;; know we're either in a multi-valued clause (in which case we know the # - ;; of vals) or we're not, in which case we only care about the first one. - (let [[val] vals] - (if (and (sym? pattern) - (or (sym? pattern :nil) - (and opts.infer-unification? - (in-scope? pattern) - (not (sym? pattern :_))) - (and opts.infer-unification? - (multi-sym? pattern) - (in-scope? (. (multi-sym? pattern) 1))))) - (values `(= ,val ,pattern) []) - ;; unify a local we've seen already - (and (sym? pattern) (. unifications (tostring pattern))) - (values `(= ,(. unifications (tostring pattern)) ,val) []) - ;; bind a fresh local - (sym? pattern) - (let [wildcard? (: (tostring pattern) :find "^_")] - (if (not wildcard?) (tset unifications (tostring pattern) val)) - (values (if (or wildcard? (string.find (tostring pattern) "^?")) true - `(not= ,(sym :nil) ,val)) [pattern val])) - ;; opt-in unify with (=) - (and (list? pattern) - (sym? (. pattern 1) :=) - (sym? (. pattern 2))) - (let [bind (. pattern 2)] - (assert-compile (= 2 (length pattern)) "(=) should take only one argument" pattern) - (assert-compile (not opts.infer-unification?) "(=) cannot be used inside of match" pattern) - (assert-compile opts.in-where? "(=) must be used in (where) patterns" pattern) - (assert-compile (and (sym? bind) (not (sym? bind :nil)) "= has to bind to a symbol" bind)) - (values `(= ,val ,bind) [])) - ;; where-or clause - (and (list? pattern) (sym? (. pattern 1) :where) (list? (. pattern 2)) (sym? (. pattern 2 1) :or)) - (do - (assert-compile ?top "can't nest (where) pattern" pattern) - (case-or vals (. pattern 2) [(unpack pattern 3)] unifications case-pattern (with opts :in-where?))) - ;; where clause - (and (list? pattern) (sym? (. pattern 1) :where)) - (do - (assert-compile ?top "can't nest (where) pattern" pattern) - (case-guard vals (. pattern 2) [(unpack pattern 3)] unifications case-pattern (with opts :in-where?))) - ;; or clause (not allowed on its own) - (and (list? pattern) (sym? (. pattern 1) :or)) - (do - (assert-compile ?top "can't nest (or) pattern" pattern) - ;; This assertion can be removed to make patterns more permissive - (assert-compile false "(or) must be used in (where) patterns" pattern) - (case-or vals pattern [] unifications case-pattern opts)) - ;; guard clause - (and (list? pattern) (sym? (. pattern 2) :?)) - (do - (assert-compile opts.legacy-guard-allowed? "legacy guard clause not supported in case" pattern) - (case-guard vals (. pattern 1) [(unpack pattern 3)] unifications case-pattern opts)) - ;; multi-valued patterns (represented as lists) - (list? pattern) - (do - (assert-compile opts.multival? "can't nest multi-value destructuring" pattern) - (case-values vals pattern unifications case-pattern opts)) - ;; table patterns - (= (type pattern) :table) - (case-table val pattern unifications case-pattern opts ?top) - ;; literal value - (values `(= ,val ,pattern) [])))) - - (fn add-pre-bindings [out pre-bindings] - "Decide when to switch from the current `if` AST to a new one" - (if pre-bindings - ;; `out` no longer needs to grow. - ;; Instead, a new tail `if` AST is introduced, which is where the rest of - ;; the clauses will get appended. This way, all future clauses have the - ;; pre-bindings in scope. - (let [tail `(if)] - (table.insert out true) - (table.insert out `(let ,pre-bindings ,tail)) - tail) - ;; otherwise, keep growing the current `if` AST. - out)) - - (fn case-condition [vals clauses match? top-table?] - "Construct the actual `if` AST for the given match values and clauses." - ;; root is the original `if` AST. - ;; out is the `if` AST that is currently being grown. - (let [root `(if)] - (faccumulate [out root - i 1 (length clauses) 2] - (let [pattern (. clauses i) - body (. clauses (+ i 1)) - (condition bindings pre-bindings) (case-pattern vals pattern {} - {:multival? true - :infer-unification? match? - :legacy-guard-allowed? match?} - (if top-table? :table true)) - out (add-pre-bindings out pre-bindings)] - ;; grow the `if` AST by one extra condition - (table.insert out condition) - (table.insert out `(let ,bindings ,body)) - out)) - root)) - - (fn count-case-multival [pattern] - "Identify the amount of multival values that a pattern requires." - (if (and (list? pattern) (sym? (. pattern 2) :?)) - (count-case-multival (. pattern 1)) - (and (list? pattern) (sym? (. pattern 1) :where)) - (count-case-multival (. pattern 2)) - (and (list? pattern) (sym? (. pattern 1) :or)) - (accumulate [longest 0 - _ child-pattern (ipairs pattern)] - (math.max longest (count-case-multival child-pattern))) - (list? pattern) - (length pattern) - 1)) - - (fn case-count-syms [clauses] - "Find the length of the largest multi-valued clause" - (let [patterns (fcollect [i 1 (length clauses) 2] - (. clauses i))] - (accumulate [longest 0 - _ pattern (ipairs patterns)] - (math.max longest (count-case-multival pattern))))) - - (fn maybe-optimize-table [val clauses] - (if (faccumulate [all (sequence? val) i 1 (length clauses) 2 &until (not all)] - (and (sequence? (. clauses i)) - (accumulate [all2 (next (. clauses i)) - _ d (ipairs (. clauses i)) &until (not all2)] - (and all2 (or (not (sym? d)) (not (: (tostring d) :find "^&"))))))) - (values `(values ,(unpack val)) - (fcollect [i 1 (length clauses)] - (if (= 1 (% i 2)) - (list (unpack (. clauses i))) - (. clauses i)))) - (values val clauses))) - - (fn case-impl [match? init-val ...] - "The shared implementation of case and match." - (assert (not= init-val nil) "missing subject") - (assert (= 0 (math.fmod (select :# ...) 2)) - "expected even number of pattern/body pairs") - (assert (not= 0 (select :# ...)) - "expected at least one pattern/body pair") - (let [(val clauses) (maybe-optimize-table init-val [...]) - vals-count (case-count-syms clauses) - skips-multiple-eval-protection? (and (= vals-count 1) (double-eval-safe? val))] - (if skips-multiple-eval-protection? - (case-condition (list val) clauses match? (table? init-val)) - ;; protect against multiple evaluation of the value, bind against as - ;; many values as we ever match against in the clauses. - (let [vals (fcollect [_ 1 vals-count &into (list)] (gensym))] - (list `let [vals val] (case-condition vals clauses match? (table? init-val))))))) - - (fn case* [val ...] - "Perform pattern matching on val. See reference for details. - - Syntax: - - (case data-expression - pattern body - (where pattern guards*) body - (where (or pattern patterns*) guards*) body)" - (case-impl false val ...)) - - (fn match* [val ...] - "Perform pattern matching on val, automatically unifying on variables in - local scope. See reference for details. - - Syntax: - - (match data-expression - pattern body - (where pattern guards*) body - (where (or pattern patterns*) guards*) body)" - (case-impl true val ...)) - - (fn case-try-step [how expr else pattern body ...] - (if (= nil pattern body) - expr - ;; unlike regular match, we can't know how many values the value - ;; might evaluate to, so we have to capture them all in ... via IIFE - ;; to avoid double-evaluation. - `((fn [...] - (,how ... - ,pattern ,(case-try-step how body else ...) - ,(unpack else))) - ,expr))) - - (fn case-try-impl [how expr pattern body ...] - (let [clauses [pattern body ...] - last (. clauses (length clauses)) - catch (if (sym? (and (= :table (type last)) (. last 1)) :catch) - (let [[_ & e] (table.remove clauses)] e) ; remove `catch sym - [`_# `...])] - (assert (= 0 (math.fmod (length clauses) 2)) - "expected every pattern to have a body") - (assert (= 0 (math.fmod (length catch) 2)) - "expected every catch pattern to have a body") - (case-try-step how expr catch (unpack clauses)))) - - (fn case-try* [expr pattern body ...] - "Perform chained pattern matching for a sequence of steps which might fail. - - The values from the initial expression are matched against the first pattern. - If they match, the first body is evaluated and its values are matched against - the second pattern, etc. - - If there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch - from the steps will be tried against these patterns in sequence as a fallback - just like a normal match. If there is no catch, the mismatched values will be - returned as the value of the entire expression." - (case-try-impl `case expr pattern body ...)) - - (fn match-try* [expr pattern body ...] - "Perform chained pattern matching for a sequence of steps which might fail. - - The values from the initial expression are matched against the first pattern. - If they match, the first body is evaluated and its values are matched against - the second pattern, etc. - - If there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch - from the steps will be tried against these patterns in sequence as a fallback - just like a normal match. If there is no catch, the mismatched values will be - returned as the value of the entire expression." - (case-try-impl `match expr pattern body ...)) - - {:case case* - :case-try case-try* - :match match* - :match-try match-try*} - ]===], {allowedGlobals = false, env = env, filename = "src/fennel/match.fnl", moduleName = module_name, scope = compiler.scopes.compiler, useMetadata = true}) - for k, v in pairs(match_macros) do - compiler.scopes.global.macros[k] = v + utils['fennel-module'].metadata:setall(__3e_3e_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Thread-last macro.\nSame as ->, except splices the value into the last position of each form\nrather than the first.") + local function __3f_3e_2a(val, _3fe, ...) + if (nil == _3fe) then + return val + elseif not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=40, bytestart=1174, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=40}), setmetatable({sym('tmp_3_', nil, {filename="src/fennel/macros.fnl", line=40}), val}, {filename="src/fennel/macros.fnl", line=40}), setmetatable({filename="src/fennel/macros.fnl", line=41, bytestart=1199, sym('-?>', nil, {quoted=true, filename="src/fennel/macros.fnl", line=41}), sym('tmp_3_', nil, {filename="src/fennel/macros.fnl", line=41}), _3fe, ...}, getmetatable(list()))}, getmetatable(list())) + else + local call = nil + if _G["list?"](_3fe) then + call = copy(_3fe) + else + call = list(_3fe) + end + table.insert(call, 2, val) + return setmetatable({filename="src/fennel/macros.fnl", line=44, bytestart=1317, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), setmetatable({filename="src/fennel/macros.fnl", line=44, bytestart=1321, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=44}), val}, getmetatable(list())), __3f_3e_2a(call, ...)}, getmetatable(list())) + end end - package.preload[module_name] = nil + utils['fennel-module'].metadata:setall(__3f_3e_2a, "fnl/arglist", {"val", "?e", "..."}, "fnl/docstring", "Nil-safe thread-first macro.\nSame as -> except will short-circuit with nil when it encounters a nil value.") + local function __3f_3e_3e_2a(val, _3fe, ...) + if (nil == _3fe) then + return val + elseif not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=54, bytestart=1627, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=54}), setmetatable({sym('tmp_6_', nil, {filename="src/fennel/macros.fnl", line=54}), val}, {filename="src/fennel/macros.fnl", line=54}), setmetatable({filename="src/fennel/macros.fnl", line=55, bytestart=1652, sym('-?>>', nil, {quoted=true, filename="src/fennel/macros.fnl", line=55}), sym('tmp_6_', nil, {filename="src/fennel/macros.fnl", line=55}), _3fe, ...}, getmetatable(list()))}, getmetatable(list())) + else + local call = nil + if _G["list?"](_3fe) then + call = copy(_3fe) + else + call = list(_3fe) + end + table.insert(call, val) + return setmetatable({filename="src/fennel/macros.fnl", line=58, bytestart=1769, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58}), setmetatable({filename="src/fennel/macros.fnl", line=58, bytestart=1773, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58}), val, sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=58})}, getmetatable(list())), __3f_3e_3e_2a(call, ...)}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(__3f_3e_3e_2a, "fnl/arglist", {"val", "?e", "..."}, "fnl/docstring", "Nil-safe thread-last macro.\nSame as ->> except will short-circuit with nil when it encounters a nil value.") + local function _3fdot(tbl, ...) + local head = gensym("t") + local lookups = setmetatable({filename="src/fennel/macros.fnl", line=66, bytestart=2024, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=66}), setmetatable({filename="src/fennel/macros.fnl", line=67, bytestart=2047, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=67}), head, tbl}, getmetatable(list())), head}, getmetatable(list())) + for i, k in ipairs({...}) do + table.insert(lookups, (i + 2), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2335, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2339, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2356, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head, setmetatable({filename="src/fennel/macros.fnl", line=73, bytestart=2367, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=73}), head, k}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))) + end + return lookups + end + utils['fennel-module'].metadata:setall(_3fdot, "fnl/arglist", {"tbl", "..."}, "fnl/docstring", "Nil-safe table look up.\nSame as . (dot), except will short-circuit with nil when it encounters\na nil value in any of subsequent keys.") + local function doto_2a(val, ...) + assert((val ~= nil), "missing subject") + if not utils["idempotent-expr?"](val) then + return setmetatable({filename="src/fennel/macros.fnl", line=80, bytestart=2585, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=80}), setmetatable({sym('tmp_9_', nil, {filename="src/fennel/macros.fnl", line=80}), val}, {filename="src/fennel/macros.fnl", line=80}), setmetatable({filename="src/fennel/macros.fnl", line=81, bytestart=2609, sym('doto', nil, {quoted=true, filename="src/fennel/macros.fnl", line=81}), sym('tmp_9_', nil, {filename="src/fennel/macros.fnl", line=81}), ...}, getmetatable(list()))}, getmetatable(list())) + else + local form = setmetatable({filename="src/fennel/macros.fnl", line=82, bytestart=2643, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=82})}, getmetatable(list())) + for _, elt in ipairs({...}) do + local elt0 = nil + if _G["list?"](elt) then + elt0 = copy(elt) + else + elt0 = list(elt) + end + table.insert(elt0, 2, val) + table.insert(form, elt0) + end + table.insert(form, val) + return form + end + end + utils['fennel-module'].metadata:setall(doto_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Evaluate val and splice it into the first argument of subsequent forms.") + local function when_2a(condition, body1, ...) + assert(body1, "expected body") + return setmetatable({filename="src/fennel/macros.fnl", line=93, bytestart=2992, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=93}), condition, setmetatable({filename="src/fennel/macros.fnl", line=94, bytestart=3014, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=94}), body1, ...}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(when_2a, "fnl/arglist", {"condition", "body1", "..."}, "fnl/docstring", "Evaluate body for side-effects only when condition is truthy.") + local function with_open_2a(closable_bindings, ...) + local bodyfn = setmetatable({filename="src/fennel/macros.fnl", line=102, bytestart=3312, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=102}), setmetatable({}, {filename="src/fennel/macros.fnl", line=102}), ...}, getmetatable(list())) + local closer = setmetatable({filename="src/fennel/macros.fnl", line=104, bytestart=3359, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=104}), sym('close-handlers_12_', nil, {filename="src/fennel/macros.fnl", line=104}), setmetatable({sym('ok_13_', nil, {filename="src/fennel/macros.fnl", line=104}), _VARARG}, {filename="src/fennel/macros.fnl", line=104}), setmetatable({filename="src/fennel/macros.fnl", line=105, bytestart=3407, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=105}), sym('ok_13_', nil, {filename="src/fennel/macros.fnl", line=105}), _VARARG, setmetatable({filename="src/fennel/macros.fnl", line=105, bytestart=3419, sym('error', nil, {quoted=true, filename="src/fennel/macros.fnl", line=105}), _VARARG, 0}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + local traceback = setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3454, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3457, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), setmetatable({filename="src/fennel/macros.fnl", line=106, bytestart=3461, sym('?.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), sym('_G', nil, {quoted=true, filename="src/fennel/macros.fnl", line=106}), "package", "loaded", _G["fennel-module-name"]()}, getmetatable(list())), sym('_G.debug', nil, {quoted=true, filename="src/fennel/macros.fnl", line=107}), setmetatable({["traceback"]=setmetatable({filename=nil, line=nil, bytestart=nil, sym('hashfn', nil, {quoted=true, filename=nil, line=nil}), ""}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=107})}, getmetatable(list())), "traceback"}, getmetatable(list())) + for i = 1, #closable_bindings, 2 do + assert(_G["sym?"](closable_bindings[i]), "with-open only allows symbols in bindings") + table.insert(closer, 4, setmetatable({filename="src/fennel/macros.fnl", line=111, bytestart=3752, sym(':', nil, {quoted=true, filename="src/fennel/macros.fnl", line=111}), closable_bindings[i], "close"}, getmetatable(list()))) + end + return setmetatable({filename="src/fennel/macros.fnl", line=112, bytestart=3795, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=112}), closable_bindings, closer, setmetatable({filename="src/fennel/macros.fnl", line=114, bytestart=3841, sym('close-handlers_12_', nil, {filename="src/fennel/macros.fnl", line=114}), setmetatable({filename="src/fennel/macros.fnl", line=114, bytestart=3858, sym('_G.xpcall', nil, {quoted=true, filename="src/fennel/macros.fnl", line=114}), bodyfn, traceback}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(with_open_2a, "fnl/arglist", {"closable-bindings", "..."}, "fnl/docstring", "Like `let`, but invokes (v:close) on each binding after evaluating the body.\nThe body is evaluated inside `xpcall` so that bound values will be closed upon\nencountering an error before propagating it.") + local function extract_into(iter_tbl) + local into, iter_out, found_3f = {}, copy(iter_tbl) + for i = #iter_tbl, 2, -1 do + local item = iter_tbl[i] + if (_G["sym?"](item, "&into") or ("into" == item)) then + assert(not found_3f, "expected only one &into clause") + found_3f = true + into = iter_tbl[(i + 1)] + table.remove(iter_out, i) + table.remove(iter_out, i) + end + end + assert((not found_3f or _G["sym?"](into) or _G["table?"](into) or _G["list?"](into)), "expected table, function call, or symbol in &into clause") + return into, iter_out, found_3f + end + utils['fennel-module'].metadata:setall(extract_into, "fnl/arglist", {"iter-tbl"}) + local function collect_2a(iter_tbl, key_expr, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 <= #iter_tbl)), "expected iterator binding table") + assert((nil ~= key_expr), "expected key and value expression") + assert((nil == ...), "expected 1 or 2 body expressions; wrap multiple expressions with do") + assert((value_expr or _G["list?"](key_expr)), "need key and value") + local kv_expr = nil + if (nil == value_expr) then + kv_expr = key_expr + else + kv_expr = setmetatable({filename="src/fennel/macros.fnl", line=151, bytestart=5514, sym('values', nil, {quoted=true, filename="src/fennel/macros.fnl", line=151}), key_expr, value_expr}, getmetatable(list())) + end + local into, iter = extract_into(iter_tbl) + return setmetatable({filename="src/fennel/macros.fnl", line=153, bytestart=5596, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=153}), setmetatable({sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=153}), into}, {filename="src/fennel/macros.fnl", line=153}), setmetatable({filename="src/fennel/macros.fnl", line=154, bytestart=5621, sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=154}), iter, setmetatable({filename="src/fennel/macros.fnl", line=155, bytestart=5642, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=155}), setmetatable({setmetatable({filename="src/fennel/macros.fnl", line=155, bytestart=5648, sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=155}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=155})}, getmetatable(list())), kv_expr}, {filename="src/fennel/macros.fnl", line=155}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5677, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5681, sym('and', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5686, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=156}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=156, bytestart=5700, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=156}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=156})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=157, bytestart=5728, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=157}), sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=157}), sym('k_17_', nil, {filename="src/fennel/macros.fnl", line=157}), sym('v_18_', nil, {filename="src/fennel/macros.fnl", line=157})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_16_', nil, {filename="src/fennel/macros.fnl", line=158})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(collect_2a, "fnl/arglist", {"iter-tbl", "key-expr", "value-expr", "..."}, "fnl/docstring", "Return a table made by running an iterator and evaluating an expression that\nreturns key-value pairs to be inserted sequentially into the table. This can\nbe thought of as a table comprehension. The body should provide two expressions\n(used as key and value) or nil, which causes it to be omitted.\n\nFor example,\n (collect [k v (pairs {:apple \"red\" :orange \"orange\"})]\n (values v k))\nreturns\n {:red \"apple\" :orange \"orange\"}\n\nSupports an &into clause after the iterator to put results in an existing table.\nSupports early termination with an &until clause.") + local function seq_collect(how, iter_tbl, value_expr, ...) + assert((nil ~= value_expr), "expected table value expression") + assert((nil == ...), "expected exactly one body expression. Wrap multiple expressions in do") + local into, iter, has_into_3f = extract_into(iter_tbl) + if has_into_3f then + return setmetatable({filename="src/fennel/macros.fnl", line=170, bytestart=6252, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=170}), setmetatable({sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=170}), into}, {filename="src/fennel/macros.fnl", line=170}), setmetatable({filename="src/fennel/macros.fnl", line=171, bytestart=6281, how, iter, setmetatable({filename="src/fennel/macros.fnl", line=171, bytestart=6293, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=171}), setmetatable({sym('val_20_', nil, {filename="src/fennel/macros.fnl", line=171}), value_expr}, {filename="src/fennel/macros.fnl", line=171}), setmetatable({filename="src/fennel/macros.fnl", line=172, bytestart=6342, sym('table.insert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=172}), sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=172}), sym('val_20_', nil, {filename="src/fennel/macros.fnl", line=172})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_19_', nil, {filename="src/fennel/macros.fnl", line=173})}, getmetatable(list())) + else + return setmetatable({filename="src/fennel/macros.fnl", line=177, bytestart=6618, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=177}), setmetatable({sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=177}), setmetatable({}, {filename="src/fennel/macros.fnl", line=177})}, {filename="src/fennel/macros.fnl", line=177}), setmetatable({filename="src/fennel/macros.fnl", line=178, bytestart=6644, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=178}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=178}), 0}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=179, bytestart=6666, how, iter, setmetatable({filename="src/fennel/macros.fnl", line=180, bytestart=6695, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=180}), setmetatable({sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=180}), value_expr}, {filename="src/fennel/macros.fnl", line=180}), setmetatable({filename="src/fennel/macros.fnl", line=181, bytestart=6738, sym('when', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), setmetatable({filename="src/fennel/macros.fnl", line=181, bytestart=6744, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=181}), sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=181})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=182, bytestart=6781, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=182}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=182}), setmetatable({filename="src/fennel/macros.fnl", line=182, bytestart=6789, sym('+', nil, {quoted=true, filename="src/fennel/macros.fnl", line=182}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=182}), 1}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=183, bytestart=6820, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=183}), sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=183}), sym('i_22_', nil, {filename="src/fennel/macros.fnl", line=183}), sym('val_23_', nil, {filename="src/fennel/macros.fnl", line=183})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('tbl_21_', nil, {filename="src/fennel/macros.fnl", line=184})}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(seq_collect, "fnl/arglist", {"how", "iter-tbl", "value-expr", "..."}, "fnl/docstring", "Common part between icollect and fcollect for producing sequential tables.\n\nIteration code only differs in using the for or each keyword, the rest\nof the generated code is identical.") + local function icollect_2a(iter_tbl, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 <= #iter_tbl)), "expected iterator binding table") + return seq_collect(sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=203}), iter_tbl, value_expr, ...) + end + utils['fennel-module'].metadata:setall(icollect_2a, "fnl/arglist", {"iter-tbl", "value-expr", "..."}, "fnl/docstring", "Return a sequential table made by running an iterator and evaluating an\nexpression that returns values to be inserted sequentially into the table.\nThis can be thought of as a table comprehension. If the body evaluates to nil\nthat element is omitted.\n\nFor example,\n (icollect [_ v (ipairs [1 2 3 4 5])]\n (when (not= v 3)\n (* v v)))\nreturns\n [1 4 16 25]\n\nSupports an &into clause after the iterator to put results in an existing table.\nSupports early termination with an &until clause.") + local function fcollect_2a(iter_tbl, value_expr, ...) + assert((_G["sequence?"](iter_tbl) and (2 < #iter_tbl)), "expected range binding table") + return seq_collect(sym('for', nil, {quoted=true, filename="src/fennel/macros.fnl", line=222}), iter_tbl, value_expr, ...) + end + utils['fennel-module'].metadata:setall(fcollect_2a, "fnl/arglist", {"iter-tbl", "value-expr", "..."}, "fnl/docstring", "Return a sequential table made by advancing a range as specified by\nfor, and evaluating an expression that returns values to be inserted\nsequentially into the table. This can be thought of as a range\ncomprehension. If the body evaluates to nil that element is omitted.\n\nFor example,\n (fcollect [i 1 10 2]\n (when (not= i 3)\n (* i i)))\nreturns\n [1 25 49 81]\n\nSupports an &into clause after the range to put results in an existing table.\nSupports early termination with an &until clause.") + local function accumulate_impl(for_3f, iter_tbl, body, ...) + assert((_G["sequence?"](iter_tbl) and (4 <= #iter_tbl)), "expected initial value and iterator binding table") + assert((nil ~= body), "expected body expression") + assert((nil == ...), "expected exactly one body expression. Wrap multiple expressions with do") + local _25_ = iter_tbl + local accum_var = _25_[1] + local accum_init = _25_[2] + local iter = nil + local function _26_(...) + if for_3f then + return "for" + else + return "each" + end + end + iter = sym(_26_(...)) + local function _27_(...) + if _G["list?"](accum_var) then + return list(sym("values"), unpack(accum_var)) + else + return accum_var + end + end + return setmetatable({filename="src/fennel/macros.fnl", line=232, bytestart=8695, sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=232}), setmetatable({filename="src/fennel/macros.fnl", line=233, bytestart=8706, sym('var', nil, {quoted=true, filename="src/fennel/macros.fnl", line=233}), accum_var, accum_init}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=234, bytestart=8742, iter, {unpack(iter_tbl, 3)}, setmetatable({filename="src/fennel/macros.fnl", line=235, bytestart=8786, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=235}), accum_var, body}, getmetatable(list()))}, getmetatable(list())), _27_(...)}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(accumulate_impl, "fnl/arglist", {"for?", "iter-tbl", "body", "..."}) + local function accumulate_2a(iter_tbl, body, ...) + return accumulate_impl(false, iter_tbl, body, ...) + end + utils['fennel-module'].metadata:setall(accumulate_2a, "fnl/arglist", {"iter-tbl", "body", "..."}, "fnl/docstring", "Accumulation macro.\n\nIt takes a binding table and an expression as its arguments. In the binding\ntable, the first form starts out bound to the second value, which is an initial\naccumulator. The rest are an iterator binding table in the format `each` takes.\n\nIt runs through the iterator in each step of which the given expression is\nevaluated, and the accumulator is set to the value of the expression. It\neventually returns the final value of the accumulator.\n\nFor example,\n (accumulate [total 0\n _ n (pairs {:apple 2 :orange 3})]\n (+ total n))\nreturns 5") + local function faccumulate_2a(iter_tbl, body, ...) + return accumulate_impl(true, iter_tbl, body, ...) + end + utils['fennel-module'].metadata:setall(faccumulate_2a, "fnl/arglist", {"iter-tbl", "body", "..."}, "fnl/docstring", "Identical to accumulate, but after the accumulator the binding table is the\nsame as `for` instead of `each`. Like collect to fcollect, will iterate over a\nnumerical range like `for` rather than an iterator.") + local function partial_2a(f, ...) + assert(f, "expected a function to partially apply") + local bindings = {} + local args = {} + for _, arg in ipairs({...}) do + if utils["idempotent-expr?"](arg) then + table.insert(args, arg) + else + local name = gensym() + table.insert(bindings, name) + table.insert(bindings, arg) + table.insert(args, name) + end + end + local body = list(f, unpack(args)) + table.insert(body, _VARARG) + if (nil == bindings[1]) then + return setmetatable({filename="src/fennel/macros.fnl", line=280, bytestart=10477, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=280}), setmetatable({_VARARG}, {filename="src/fennel/macros.fnl", line=280}), body}, getmetatable(list())) + else + return setmetatable({filename="src/fennel/macros.fnl", line=281, bytestart=10510, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=281}), bindings, setmetatable({filename="src/fennel/macros.fnl", line=282, bytestart=10538, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=282}), setmetatable({_VARARG}, {filename="src/fennel/macros.fnl", line=282}), body}, getmetatable(list()))}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(partial_2a, "fnl/arglist", {"f", "..."}, "fnl/docstring", "Return a function with all arguments partially applied to f.") + local function pick_args_2a(n, f) + if (_G.io and _G.io.stderr) then + do end (_G.io.stderr):write("-- WARNING: pick-args is deprecated and will be removed in the future.\n") + end + local bindings = {} + for i = 1, n do + bindings[i] = gensym() + end + return setmetatable({filename="src/fennel/macros.fnl", line=291, bytestart=10877, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=291}), bindings, setmetatable({filename="src/fennel/macros.fnl", line=291, bytestart=10891, f, unpack(bindings)}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(pick_args_2a, "fnl/arglist", {"n", "f"}, "fnl/docstring", "Create a function of arity n that applies its arguments to f. Deprecated.") + local function lambda_2a(...) + local args = {...} + local args_len = #args + local has_internal_name_3f = _G["sym?"](args[1]) + local arglist = nil + if has_internal_name_3f then + arglist = args[2] + else + arglist = args[1] + end + local metadata_position = nil + if has_internal_name_3f then + metadata_position = 3 + else + metadata_position = 2 + end + local _, check_position = _G["get-function-metadata"]({"lambda", ...}, arglist, metadata_position) + local empty_body_3f = (args_len < check_position) + local function check_21(a) + if _G["table?"](a) then + for _0, a0 in pairs(a) do + check_21(a0) + end + return nil + else + local _33_ + do + local as = tostring(a) + local as1 = as:sub(1, 1) + _33_ = not (("_" == as1) or ("?" == as1) or ("&" == as) or ("..." == as) or ("&as" == as)) + end + if _33_ then + return table.insert(args, check_position, setmetatable({filename="src/fennel/macros.fnl", line=312, bytestart=11826, sym('_G.assert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), setmetatable({filename="src/fennel/macros.fnl", line=312, bytestart=11837, sym('not=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=312}), a}, getmetatable(list())), ("Missing argument %s on %s:%s"):format(tostring(a), (a.filename or "unknown"), (a.line or "?"))}, getmetatable(list()))) + end + end + end + utils['fennel-module'].metadata:setall(check_21, "fnl/arglist", {"a"}) + assert(("table" == type(arglist)), "expected arg list") + for _0, a in ipairs(arglist) do + check_21(a) + end + if empty_body_3f then + table.insert(args, sym("nil")) + end + return setmetatable({filename="src/fennel/macros.fnl", line=321, bytestart=12271, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=321}), unpack(args)}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(lambda_2a, "fnl/arglist", {"..."}, "fnl/docstring", "Function literal with nil-checked arguments.\nLike `fn`, but will throw an exception if a declared argument is passed in as\nnil, unless that argument's name begins with a question mark.") + local function macro_2a(name, ...) + assert(_G["sym?"](name), "expected symbol for macro name") + local args = {...} + return setmetatable({filename="src/fennel/macros.fnl", line=327, bytestart=12423, sym('macros', nil, {quoted=true, filename="src/fennel/macros.fnl", line=327}), setmetatable({[tostring(name)]=setmetatable({filename="src/fennel/macros.fnl", line=327, bytestart=12449, sym('fn', nil, {quoted=true, filename="src/fennel/macros.fnl", line=327}), unpack(args)}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=327})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(macro_2a, "fnl/arglist", {"name", "..."}, "fnl/docstring", "Define a single macro.") + local function macrodebug_2a(form, return_3f) + local handle = nil + if return_3f then + handle = sym('do', nil, {quoted=true, filename="src/fennel/macros.fnl", line=332}) + else + handle = sym('print', nil, {quoted=true, filename="src/fennel/macros.fnl", line=332}) + end + return setmetatable({filename="src/fennel/macros.fnl", line=335, bytestart=12845, handle, view(macroexpand(form, _SCOPE), {["detect-cycles?"] = false})}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(macrodebug_2a, "fnl/arglist", {"form", "return?"}, "fnl/docstring", "Print the resulting form after performing macroexpansion.\nWith a second argument, returns expanded form as a string instead of printing.") + local function import_macros_2a(binding1, module_name1, ...) + assert((binding1 and module_name1 and (0 == (select("#", ...) % 2))), "expected even number of binding/modulename pairs") + for i = 1, select("#", binding1, module_name1, ...), 2 do + local binding, modname = select(i, binding1, module_name1, ...) + local scope = _G["get-scope"]() + local expr = setmetatable({filename="src/fennel/macros.fnl", line=354, bytestart=14006, sym('import-macros', nil, {quoted=true, filename="src/fennel/macros.fnl", line=354}), modname}, getmetatable(list())) + local filename = nil + if _G["list?"](modname) then + filename = modname[1].filename + else + filename = "unknown" + end + local _ = nil + expr.filename = filename + _ = nil + local macros_2a = _SPECIALS["require-macros"](expr, scope, {}, binding) + if _G["sym?"](binding) then + scope.macros[binding[1]] = macros_2a + elseif _G["table?"](binding) then + for macro_name, _38_0 in pairs(binding) do + local _39_ = _38_0 + local import_key = _39_[1] + assert(("function" == type(macros_2a[macro_name])), ("macro " .. macro_name .. " not found in module " .. tostring(modname))) + scope.macros[import_key] = macros_2a[macro_name] + end + end + end + return nil + end + utils['fennel-module'].metadata:setall(import_macros_2a, "fnl/arglist", {"binding1", "module-name1", "..."}, "fnl/docstring", "Bind a table of macros from each macro module according to a binding form.\nEach binding form can be either a symbol or a k/v destructuring table.\nExample:\n (import-macros mymacros :my-macros ; bind to symbol\n {:macro1 alias : macro2} :proj.macros) ; import by name") + local function assert_repl_2a(condition, ...) + do local _ = {["fnl/arglist"] = {condition, _G["?message"], ...}} end + local function add_locals(_41_0, locals) + local _42_ = _41_0 + local parent = _42_["parent"] + local symmeta = _42_["symmeta"] + for name in pairs(symmeta) do + locals[name] = sym(name) + end + if parent then + return add_locals(parent, locals) + else + return locals + end + end + utils['fennel-module'].metadata:setall(add_locals, "fnl/arglist", {"#
", "locals"}) + return setmetatable({filename="src/fennel/macros.fnl", line=379, bytestart=15225, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), setmetatable({sym('unpack_44_', nil, {filename="src/fennel/macros.fnl", line=379}), setmetatable({filename="src/fennel/macros.fnl", line=379, bytestart=15239, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), sym('table.unpack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379}), sym('_G.unpack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=379})}, getmetatable(list())), sym('pack_46_', nil, {filename="src/fennel/macros.fnl", line=380}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15282, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), sym('table.pack', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), setmetatable({filename=nil, line=nil, bytestart=nil, sym('hashfn', nil, {quoted=true, filename=nil, line=nil}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15298, sym('doto', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), setmetatable({sym('$...', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380})}, {filename="src/fennel/macros.fnl", line=380}), setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15311, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), "n", setmetatable({filename="src/fennel/macros.fnl", line=380, bytestart=15320, sym('select', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380}), "#", sym('$...', nil, {quoted=true, filename="src/fennel/macros.fnl", line=380})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=383}), setmetatable({filename="src/fennel/macros.fnl", line=383, bytestart=15493, sym('pack_46_', nil, {filename="src/fennel/macros.fnl", line=383}), condition, ...}, getmetatable(list())), sym('condition_47_', nil, {filename="src/fennel/macros.fnl", line=384}), setmetatable({filename="src/fennel/macros.fnl", line=384, bytestart=15537, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=384}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=384}), 1}, getmetatable(list())), sym('message_48_', nil, {filename="src/fennel/macros.fnl", line=385}), setmetatable({filename="src/fennel/macros.fnl", line=385, bytestart=15567, sym('or', nil, {quoted=true, filename="src/fennel/macros.fnl", line=385}), setmetatable({filename="src/fennel/macros.fnl", line=385, bytestart=15571, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=385}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=385}), 2}, getmetatable(list())), "assertion failed, entering repl."}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=379}), setmetatable({filename="src/fennel/macros.fnl", line=386, bytestart=15625, sym('if', nil, {quoted=true, filename="src/fennel/macros.fnl", line=386}), setmetatable({filename="src/fennel/macros.fnl", line=386, bytestart=15629, sym('not', nil, {quoted=true, filename="src/fennel/macros.fnl", line=386}), sym('condition_47_', nil, {filename="src/fennel/macros.fnl", line=386})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=387, bytestart=15655, sym('let', nil, {quoted=true, filename="src/fennel/macros.fnl", line=387}), setmetatable({sym('opts_49_', nil, {filename="src/fennel/macros.fnl", line=387}), setmetatable({["assert-repl?"]=true}, {filename="src/fennel/macros.fnl", line=387}), sym('fennel_50_', nil, {filename="src/fennel/macros.fnl", line=388}), setmetatable({filename="src/fennel/macros.fnl", line=388, bytestart=15711, sym('require', nil, {quoted=true, filename="src/fennel/macros.fnl", line=388}), _G["fennel-module-name"]()}, getmetatable(list())), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=389}), add_locals(_G["get-scope"](), {})}, {filename="src/fennel/macros.fnl", line=387}), setmetatable({filename="src/fennel/macros.fnl", line=390, bytestart=15807, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=390}), sym('opts_49_.message', nil, {filename="src/fennel/macros.fnl", line=390}), setmetatable({filename="src/fennel/macros.fnl", line=390, bytestart=15826, sym('fennel_50_.traceback', nil, {filename="src/fennel/macros.fnl", line=390}), sym('message_48_', nil, {filename="src/fennel/macros.fnl", line=390})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=391, bytestart=15867, sym('each', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391}), setmetatable({sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=391}), sym('v_53_', nil, {filename="src/fennel/macros.fnl", line=391}), setmetatable({filename="src/fennel/macros.fnl", line=391, bytestart=15880, sym('pairs', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391}), sym('_G', nil, {quoted=true, filename="src/fennel/macros.fnl", line=391})}, getmetatable(list()))}, {filename="src/fennel/macros.fnl", line=391}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15905, sym('when', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15911, sym('=', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('nil', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15918, sym('.', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=392})}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=392, bytestart=15934, sym('tset', nil, {quoted=true, filename="src/fennel/macros.fnl", line=392}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('k_52_', nil, {filename="src/fennel/macros.fnl", line=392}), sym('v_53_', nil, {filename="src/fennel/macros.fnl", line=392})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=393, bytestart=15968, sym('set', nil, {quoted=true, filename="src/fennel/macros.fnl", line=393}), sym('opts_49_.env', nil, {filename="src/fennel/macros.fnl", line=393}), sym('locals_51_', nil, {filename="src/fennel/macros.fnl", line=393})}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=394, bytestart=16003, sym('_G.assert', nil, {quoted=true, filename="src/fennel/macros.fnl", line=394}), setmetatable({filename="src/fennel/macros.fnl", line=394, bytestart=16014, sym('fennel_50_.repl', nil, {filename="src/fennel/macros.fnl", line=394}), sym('opts_49_', nil, {filename="src/fennel/macros.fnl", line=394})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())), setmetatable({filename="src/fennel/macros.fnl", line=395, bytestart=16046, sym('values', nil, {quoted=true, filename="src/fennel/macros.fnl", line=395}), setmetatable({filename="src/fennel/macros.fnl", line=395, bytestart=16054, sym('unpack_44_', nil, {filename="src/fennel/macros.fnl", line=395}), sym('vals_45_', nil, {filename="src/fennel/macros.fnl", line=395}), 1, sym('vals_45_.n', nil, {filename="src/fennel/macros.fnl", line=395})}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list()))}, getmetatable(list())) + end + utils['fennel-module'].metadata:setall(assert_repl_2a, "fnl/arglist", {"condition", "..."}, "fnl/docstring", "Enter into a debug REPL and print the message when condition is false/nil.\nWorks as a drop-in replacement for Lua's `assert`.\nREPL `,return` command returns values to assert in place to continue execution.") + return {["->"] = __3e_2a, ["->>"] = __3e_3e_2a, ["-?>"] = __3f_3e_2a, ["-?>>"] = __3f_3e_3e_2a, ["?."] = _3fdot, ["\206\187"] = lambda_2a, ["assert-repl"] = assert_repl_2a, ["import-macros"] = import_macros_2a, ["pick-args"] = pick_args_2a, ["with-open"] = with_open_2a, accumulate = accumulate_2a, collect = collect_2a, doto = doto_2a, faccumulate = faccumulate_2a, fcollect = fcollect_2a, icollect = icollect_2a, lambda = lambda_2a, macro = macro_2a, macrodebug = macrodebug_2a, partial = partial_2a, when = when_2a} + ]===], env) + load_macros([===[local function copy(t) + local tbl_14_ = {} + for k, v in pairs(t) do + local k_15_, v_16_ = k, v + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + return tbl_14_ + end + utils['fennel-module'].metadata:setall(copy, "fnl/arglist", {"t"}) + local function double_eval_safe_3f(x, type) + return (("number" == type) or ("string" == type) or ("boolean" == type) or (_G["sym?"](x) and not _G["multi-sym?"](x))) + end + utils['fennel-module'].metadata:setall(double_eval_safe_3f, "fnl/arglist", {"x", "type"}) + local function with(opts, k) + local _2_0 = copy(opts) + _2_0[k] = true + return _2_0 + end + utils['fennel-module'].metadata:setall(with, "fnl/arglist", {"opts", "k"}) + local function without(opts, k) + local _3_0 = copy(opts) + _3_0[k] = nil + return _3_0 + end + utils['fennel-module'].metadata:setall(without, "fnl/arglist", {"opts", "k"}) + local function case_values(vals, pattern, unifications, case_pattern, opts) + local condition = setmetatable({filename="src/fennel/match.fnl", line=20, bytestart=528, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=20})}, getmetatable(list())) + local bindings = {} + for i, pat in ipairs(pattern) do + local subcondition, subbindings = case_pattern({vals[i]}, pat, unifications, without(opts, "multival?")) + table.insert(condition, subcondition) + local tbl_17_ = bindings + local i_18_ = #tbl_17_ + for _, b in ipairs(subbindings) do + local val_19_ = b + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + end + return condition, bindings + end + utils['fennel-module'].metadata:setall(case_values, "fnl/arglist", {"vals", "pattern", "unifications", "case-pattern", "opts"}) + local function case_table(val, pattern, unifications, case_pattern, opts, _3ftop) + local condition = nil + if ("table" == _3ftop) then + condition = setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1005, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=30})}, getmetatable(list())) + else + condition = setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1012, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1017, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), setmetatable({filename="src/fennel/match.fnl", line=30, bytestart=1020, sym('_G.type', nil, {quoted=true, filename="src/fennel/match.fnl", line=30}), val}, getmetatable(list())), "table"}, getmetatable(list()))}, getmetatable(list())) + end + local bindings = {} + for k, pat in pairs(pattern) do + if _G["sym?"](pat, "&") then + local rest_pat = pattern[(k + 1)] + local rest_val = setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1195, sym('select', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), k, setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1206, setmetatable({filename="src/fennel/match.fnl", line=35, bytestart=1207, sym('or', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), sym('table.unpack', nil, {quoted=true, filename="src/fennel/match.fnl", line=35}), sym('_G.unpack', nil, {quoted=true, filename="src/fennel/match.fnl", line=35})}, getmetatable(list())), val}, getmetatable(list()))}, getmetatable(list())) + local subcondition = case_table(setmetatable({filename="src/fennel/match.fnl", line=36, bytestart=1284, sym('pick-values', nil, {quoted=true, filename="src/fennel/match.fnl", line=36}), 1, rest_val}, getmetatable(list())), rest_pat, unifications, case_pattern, without(opts, "multival?")) + if not _G["sym?"](rest_pat) then + table.insert(condition, subcondition) + end + assert((nil == pattern[(k + 2)]), "expected & rest argument before last parameter") + table.insert(bindings, rest_pat) + table.insert(bindings, {rest_val}) + elseif _G["sym?"](k, "&as") then + table.insert(bindings, pat) + table.insert(bindings, val) + elseif (("number" == type(k)) and _G["sym?"](pat, "&as")) then + assert((nil == pattern[(k + 2)]), "expected &as argument before last parameter") + table.insert(bindings, pattern[(k + 1)]) + table.insert(bindings, val) + elseif (("number" ~= type(k)) or (not _G["sym?"](pattern[(k - 1)], "&as") and not _G["sym?"](pattern[(k - 1)], "&"))) then + local subval = setmetatable({filename="src/fennel/match.fnl", line=58, bytestart=2418, sym('.', nil, {quoted=true, filename="src/fennel/match.fnl", line=58}), val, k}, getmetatable(list())) + local subcondition, subbindings = case_pattern({subval}, pat, unifications, without(opts, "multival?")) + table.insert(condition, subcondition) + local tbl_17_ = bindings + local i_18_ = #tbl_17_ + for _, b in ipairs(subbindings) do + local val_19_ = b + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + end + end + return condition, bindings + end + utils['fennel-module'].metadata:setall(case_table, "fnl/arglist", {"val", "pattern", "unifications", "case-pattern", "opts", "?top"}) + local function case_guard(vals, condition, guards, unifications, case_pattern, opts) + if guards[1] then + local pcondition, bindings = case_pattern(vals, condition, unifications, opts) + local condition0 = setmetatable({filename="src/fennel/match.fnl", line=69, bytestart=3002, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=69}), unpack(guards)}, getmetatable(list())) + return setmetatable({filename="src/fennel/match.fnl", line=70, bytestart=3042, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=70}), pcondition, setmetatable({filename="src/fennel/match.fnl", line=71, bytestart=3080, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=71}), bindings, condition0}, getmetatable(list()))}, getmetatable(list())), bindings + else + return case_pattern(vals, condition, unifications, opts) + end + end + utils['fennel-module'].metadata:setall(case_guard, "fnl/arglist", {"vals", "condition", "guards", "unifications", "case-pattern", "opts"}) + local function symbols_in_pattern(pattern) + if _G["list?"](pattern) then + if (_G["sym?"](pattern[1], "where") or _G["sym?"](pattern[1], "=")) then + return symbols_in_pattern(pattern[2]) + elseif _G["sym?"](pattern[2], "?") then + return symbols_in_pattern(pattern[1]) + else + local result = {} + for _, child_pattern in ipairs(pattern) do + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(child_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + return result + end + elseif _G["sym?"](pattern) then + if (not _G["sym?"](pattern, "or") and not _G["sym?"](pattern, "nil")) then + return {[tostring(pattern)] = pattern} + else + return {} + end + elseif (type(pattern) == "table") then + local result = {} + for key_pattern, value_pattern in pairs(pattern) do + do + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(key_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + local tbl_14_ = result + for name, symbol in pairs(symbols_in_pattern(value_pattern)) do + local k_15_, v_16_ = name, symbol + if ((k_15_ ~= nil) and (v_16_ ~= nil)) then + tbl_14_[k_15_] = v_16_ + end + end + end + return result + else + return {} + end + end + utils['fennel-module'].metadata:setall(symbols_in_pattern, "fnl/arglist", {"pattern"}, "fnl/docstring", "gives the set of symbols inside a pattern") + local function symbols_in_every_pattern(pattern_list, infer_unification_3f) + local _3fsymbols = nil + do + local _3fsymbols0 = nil + for _, pattern in ipairs(pattern_list) do + local in_pattern = symbols_in_pattern(pattern) + if _3fsymbols0 then + for name in pairs(_3fsymbols0) do + if not in_pattern[name] then + _3fsymbols0[name] = nil + end + end + _3fsymbols0 = _3fsymbols0 + else + _3fsymbols0 = in_pattern + end + end + _3fsymbols = _3fsymbols0 + end + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for _, symbol in pairs((_3fsymbols or {})) do + local val_19_ = nil + if not (infer_unification_3f and _G["in-scope?"](symbol)) then + val_19_ = symbol + else + val_19_ = nil + end + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + return tbl_17_ + end + utils['fennel-module'].metadata:setall(symbols_in_every_pattern, "fnl/arglist", {"pattern-list", "infer-unification?"}, "fnl/docstring", "gives a list of symbols that are present in every pattern in the list") + local function case_or(vals, pattern, guards, unifications, case_pattern, opts) + local pattern0 = {unpack(pattern, 2)} + local bindings = symbols_in_every_pattern(pattern0, opts["infer-unification?"]) + if (nil == bindings[1]) then + local condition = nil + do + local tbl_17_ = setmetatable({filename="src/fennel/match.fnl", line=125, bytestart=5354, sym('or', nil, {quoted=true, filename="src/fennel/match.fnl", line=125})}, getmetatable(list())) + local i_18_ = #tbl_17_ + for _, subpattern in ipairs(pattern0) do + local val_19_ = case_pattern(vals, subpattern, unifications, opts) + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + condition = tbl_17_ + end + local _21_ + if guards[1] then + _21_ = setmetatable({filename="src/fennel/match.fnl", line=128, bytestart=5495, sym('and', nil, {quoted=true, filename="src/fennel/match.fnl", line=128}), condition, unpack(guards)}, getmetatable(list())) + else + _21_ = condition + end + return _21_, {} + else + local matched_3f = gensym("matched?") + local bindings_mangled = nil + do + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for _, binding in ipairs(bindings) do + local val_19_ = gensym(tostring(binding)) + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + bindings_mangled = tbl_17_ + end + local pre_bindings = setmetatable({filename="src/fennel/match.fnl", line=135, bytestart=5870, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=135})}, getmetatable(list())) + for _, subpattern in ipairs(pattern0) do + local subcondition, subbindings = case_guard(vals, subpattern, guards, {}, case_pattern, opts) + table.insert(pre_bindings, subcondition) + table.insert(pre_bindings, setmetatable({filename="src/fennel/match.fnl", line=139, bytestart=6116, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=139}), subbindings, setmetatable({filename="src/fennel/match.fnl", line=140, bytestart=6176, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=140}), true, unpack(bindings)}, getmetatable(list()))}, getmetatable(list()))) + end + return matched_3f, {setmetatable({filename="src/fennel/match.fnl", line=142, bytestart=6256, unpack(bindings)}, getmetatable(list())), setmetatable({filename="src/fennel/match.fnl", line=142, bytestart=6278, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=142}), unpack(bindings_mangled)}, getmetatable(list()))}, {setmetatable({filename="src/fennel/match.fnl", line=143, bytestart=6333, matched_3f, unpack(bindings_mangled)}, getmetatable(list())), pre_bindings} + end + end + utils['fennel-module'].metadata:setall(case_or, "fnl/arglist", {"vals", "pattern", "guards", "unifications", "case-pattern", "opts"}) + local function case_pattern(vals, pattern, unifications, opts, _3ftop) + local _25_ = vals + local val = _25_[1] + if (_G["sym?"](pattern) and (_G["sym?"](pattern, "nil") or (opts["infer-unification?"] and _G["in-scope?"](pattern) and not _G["sym?"](pattern, "_")) or (opts["infer-unification?"] and _G["multi-sym?"](pattern) and _G["in-scope?"](_G["multi-sym?"](pattern)[1])))) then + return setmetatable({filename="src/fennel/match.fnl", line=177, bytestart=8254, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=177}), val, pattern}, getmetatable(list())), {} + elseif (_G["sym?"](pattern) and unifications[tostring(pattern)]) then + return setmetatable({filename="src/fennel/match.fnl", line=180, bytestart=8402, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=180}), unifications[tostring(pattern)], val}, getmetatable(list())), {} + elseif _G["sym?"](pattern) then + local wildcard_3f = tostring(pattern):find("^_") + if not wildcard_3f then + unifications[tostring(pattern)] = val + end + local _27_ + if (wildcard_3f or string.find(tostring(pattern), "^?")) then + _27_ = true + else + _27_ = setmetatable({filename="src/fennel/match.fnl", line=186, bytestart=8741, sym('not=', nil, {quoted=true, filename="src/fennel/match.fnl", line=186}), sym("nil"), val}, getmetatable(list())) + end + return _27_, {pattern, val} + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "=") and _G["sym?"](pattern[2])) then + local bind = pattern[2] + _G["assert-compile"]((2 == #pattern), "(=) should take only one argument", pattern) + _G["assert-compile"](not opts["infer-unification?"], "(=) cannot be used inside of match", pattern) + _G["assert-compile"](opts["in-where?"], "(=) must be used in (where) patterns", pattern) + _G["assert-compile"]((_G["sym?"](bind) and not _G["sym?"](bind, "nil") and "= has to bind to a symbol" and bind)) + return setmetatable({filename="src/fennel/match.fnl", line=196, bytestart=9355, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=196}), val, bind}, getmetatable(list())), {} + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where") and _G["list?"](pattern[2]) and _G["sym?"](pattern[2][1], "or")) then + _G["assert-compile"](_3ftop, "can't nest (where) pattern", pattern) + return case_or(vals, pattern[2], {unpack(pattern, 3)}, unifications, case_pattern, with(opts, "in-where?")) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where")) then + _G["assert-compile"](_3ftop, "can't nest (where) pattern", pattern) + return case_guard(vals, pattern[2], {unpack(pattern, 3)}, unifications, case_pattern, with(opts, "in-where?")) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "or")) then + _G["assert-compile"](_3ftop, "can't nest (or) pattern", pattern) + _G["assert-compile"](false, "(or) must be used in (where) patterns", pattern) + return case_or(vals, pattern, {}, unifications, case_pattern, opts) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[2], "?")) then + _G["assert-compile"](opts["legacy-guard-allowed?"], "legacy guard clause not supported in case", pattern) + return case_guard(vals, pattern[1], {unpack(pattern, 3)}, unifications, case_pattern, opts) + elseif _G["list?"](pattern) then + _G["assert-compile"](opts["multival?"], "can't nest multi-value destructuring", pattern) + return case_values(vals, pattern, unifications, case_pattern, opts) + elseif (type(pattern) == "table") then + return case_table(val, pattern, unifications, case_pattern, opts, _3ftop) + else + return setmetatable({filename="src/fennel/match.fnl", line=228, bytestart=11092, sym('=', nil, {quoted=true, filename="src/fennel/match.fnl", line=228}), val, pattern}, getmetatable(list())), {} + end + end + utils['fennel-module'].metadata:setall(case_pattern, "fnl/arglist", {"vals", "pattern", "unifications", "opts", "?top"}, "fnl/docstring", "Take the AST of values and a single pattern and returns a condition\nto determine if it matches as well as a list of bindings to\nintroduce for the duration of the body if it does match.") + local function add_pre_bindings(out, pre_bindings) + if pre_bindings then + local tail = setmetatable({filename="src/fennel/match.fnl", line=237, bytestart=11490, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=237})}, getmetatable(list())) + table.insert(out, true) + table.insert(out, setmetatable({filename="src/fennel/match.fnl", line=239, bytestart=11555, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=239}), pre_bindings, tail}, getmetatable(list()))) + return tail + else + return out + end + end + utils['fennel-module'].metadata:setall(add_pre_bindings, "fnl/arglist", {"out", "pre-bindings"}, "fnl/docstring", "Decide when to switch from the current `if` AST to a new one") + local function case_condition(vals, clauses, match_3f, top_table_3f) + local root = setmetatable({filename="src/fennel/match.fnl", line=248, bytestart=11896, sym('if', nil, {quoted=true, filename="src/fennel/match.fnl", line=248})}, getmetatable(list())) + do + local out = root + for i = 1, #clauses, 2 do + local pattern = clauses[i] + local body = clauses[(i + 1)] + local condition, bindings, pre_bindings = nil, nil, nil + local function _31_() + if top_table_3f then + return "table" + else + return true + end + end + condition, bindings, pre_bindings = case_pattern(vals, pattern, {}, {["infer-unification?"] = match_3f, ["legacy-guard-allowed?"] = match_3f, ["multival?"] = true}, _31_()) + local out0 = add_pre_bindings(out, pre_bindings) + table.insert(out0, condition) + table.insert(out0, setmetatable({filename="src/fennel/match.fnl", line=261, bytestart=12633, sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=261}), bindings, body}, getmetatable(list()))) + out = out0 + end + end + return root + end + utils['fennel-module'].metadata:setall(case_condition, "fnl/arglist", {"vals", "clauses", "match?", "top-table?"}, "fnl/docstring", "Construct the actual `if` AST for the given match values and clauses.") + local function count_case_multival(pattern) + if (_G["list?"](pattern) and _G["sym?"](pattern[2], "?")) then + return count_case_multival(pattern[1]) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "where")) then + return count_case_multival(pattern[2]) + elseif (_G["list?"](pattern) and _G["sym?"](pattern[1], "or")) then + local longest = 0 + for _, child_pattern in ipairs(pattern) do + longest = math.max(longest, count_case_multival(child_pattern)) + end + return longest + elseif _G["list?"](pattern) then + return #pattern + else + return 1 + end + end + utils['fennel-module'].metadata:setall(count_case_multival, "fnl/arglist", {"pattern"}, "fnl/docstring", "Identify the amount of multival values that a pattern requires.") + local function case_count_syms(clauses) + local patterns = nil + do + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for i = 1, #clauses, 2 do + local val_19_ = clauses[i] + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + patterns = tbl_17_ + end + local longest = 0 + for _, pattern in ipairs(patterns) do + longest = math.max(longest, count_case_multival(pattern)) + end + return longest + end + utils['fennel-module'].metadata:setall(case_count_syms, "fnl/arglist", {"clauses"}, "fnl/docstring", "Find the length of the largest multi-valued clause") + local function maybe_optimize_table(val, clauses) + local _34_ + do + local all = _G["sequence?"](val) + for i = 1, #clauses, 2 do + if not all then break end + local function _35_() + local all2 = next(clauses[i]) + for _, d in ipairs(clauses[i]) do + if not all2 then break end + all2 = (all2 and (not _G["sym?"](d) or not tostring(d):find("^&"))) + end + return all2 + end + all = (_G["sequence?"](clauses[i]) and _35_()) + end + _34_ = all + end + if _34_ then + local function _36_() + local tbl_17_ = {} + local i_18_ = #tbl_17_ + for i = 1, #clauses do + local val_19_ = nil + if (1 == (i % 2)) then + val_19_ = list(unpack(clauses[i])) + else + val_19_ = clauses[i] + end + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + return tbl_17_ + end + return setmetatable({filename="src/fennel/match.fnl", line=293, bytestart=13916, sym('values', nil, {quoted=true, filename="src/fennel/match.fnl", line=293}), unpack(val)}, getmetatable(list())), _36_() + else + return val, clauses + end + end + utils['fennel-module'].metadata:setall(maybe_optimize_table, "fnl/arglist", {"val", "clauses"}) + local function case_impl(match_3f, init_val, ...) + assert((init_val ~= nil), "missing subject") + assert((0 == math.fmod(select("#", ...), 2)), "expected even number of pattern/body pairs") + assert((0 ~= select("#", ...)), "expected at least one pattern/body pair") + local val, clauses = maybe_optimize_table(init_val, {...}) + local vals_count = case_count_syms(clauses) + local skips_multiple_eval_protection_3f = ((vals_count == 1) and double_eval_safe_3f(val)) + if skips_multiple_eval_protection_3f then + return case_condition(list(val), clauses, match_3f, _G["table?"](init_val)) + else + local vals = nil + do + local tbl_17_ = list() + local i_18_ = #tbl_17_ + for _ = 1, vals_count do + local val_19_ = gensym() + if (nil ~= val_19_) then + i_18_ = (i_18_ + 1) + tbl_17_[i_18_] = val_19_ + end + end + vals = tbl_17_ + end + return list(sym('let', nil, {quoted=true, filename="src/fennel/match.fnl", line=315}), {vals, val}, case_condition(vals, clauses, match_3f, _G["table?"](init_val))) + end + end + utils['fennel-module'].metadata:setall(case_impl, "fnl/arglist", {"match?", "init-val", "..."}, "fnl/docstring", "The shared implementation of case and match.") + local function case_2a(val, ...) + return case_impl(false, val, ...) + end + utils['fennel-module'].metadata:setall(case_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Perform pattern matching on val. See reference for details.\n\nSyntax:\n\n(case data-expression\n pattern body\n (where pattern guards*) body\n (where (or pattern patterns*) guards*) body)") + local function match_2a(val, ...) + return case_impl(true, val, ...) + end + utils['fennel-module'].metadata:setall(match_2a, "fnl/arglist", {"val", "..."}, "fnl/docstring", "Perform pattern matching on val, automatically unifying on variables in\nlocal scope. See reference for details.\n\nSyntax:\n\n(match data-expression\n pattern body\n (where pattern guards*) body\n (where (or pattern patterns*) guards*) body)") + local function case_try_step(how, expr, _else, pattern, body, ...) + if ((nil == pattern) and (pattern == body)) then + return expr + else + return setmetatable({filename="src/fennel/match.fnl", line=346, bytestart=15867, setmetatable({filename="src/fennel/match.fnl", line=346, bytestart=15868, sym('fn', nil, {quoted=true, filename="src/fennel/match.fnl", line=346}), setmetatable({_VARARG}, {filename="src/fennel/match.fnl", line=346}), setmetatable({filename="src/fennel/match.fnl", line=347, bytestart=15888, how, _VARARG, pattern, case_try_step(how, body, _else, ...), unpack(_else)}, getmetatable(list()))}, getmetatable(list())), expr}, getmetatable(list())) + end + end + utils['fennel-module'].metadata:setall(case_try_step, "fnl/arglist", {"how", "expr", "else", "pattern", "body", "..."}) + local function case_try_impl(how, expr, pattern, body, ...) + local clauses = {pattern, body, ...} + local last = clauses[#clauses] + local catch = nil + if _G["sym?"]((("table" == type(last)) and last[1]), "catch") then + local _43_ = table.remove(clauses) + local _ = _43_[1] + local e = {(table.unpack or unpack)(_43_, 2)} + catch = e + else + catch = {sym('__44_', nil, {filename="src/fennel/match.fnl", line=357}), _VARARG} + end + assert((0 == math.fmod(#clauses, 2)), "expected every pattern to have a body") + assert((0 == math.fmod(#catch, 2)), "expected every catch pattern to have a body") + return case_try_step(how, expr, catch, unpack(clauses)) + end + utils['fennel-module'].metadata:setall(case_try_impl, "fnl/arglist", {"how", "expr", "pattern", "body", "..."}) + local function case_try_2a(expr, pattern, body, ...) + return case_try_impl(sym('case', nil, {quoted=true, filename="src/fennel/match.fnl", line=375}), expr, pattern, body, ...) + end + utils['fennel-module'].metadata:setall(case_try_2a, "fnl/arglist", {"expr", "pattern", "body", "..."}, "fnl/docstring", "Perform chained pattern matching for a sequence of steps which might fail.\n\nThe values from the initial expression are matched against the first pattern.\nIf they match, the first body is evaluated and its values are matched against\nthe second pattern, etc.\n\nIf there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch\nfrom the steps will be tried against these patterns in sequence as a fallback\njust like a normal match. If there is no catch, the mismatched values will be\nreturned as the value of the entire expression.") + local function match_try_2a(expr, pattern, body, ...) + return case_try_impl(sym('match', nil, {quoted=true, filename="src/fennel/match.fnl", line=388}), expr, pattern, body, ...) + end + utils['fennel-module'].metadata:setall(match_try_2a, "fnl/arglist", {"expr", "pattern", "body", "..."}, "fnl/docstring", "Perform chained pattern matching for a sequence of steps which might fail.\n\nThe values from the initial expression are matched against the first pattern.\nIf they match, the first body is evaluated and its values are matched against\nthe second pattern, etc.\n\nIf there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch\nfrom the steps will be tried against these patterns in sequence as a fallback\njust like a normal match. If there is no catch, the mismatched values will be\nreturned as the value of the entire expression.") + return {["case-try"] = case_try_2a, ["match-try"] = match_try_2a, case = case_2a, match = match_2a} + ]===], env) end return mod end fennel = require("fennel") -local unpack = (table.unpack or _G.unpack) +local _863_ = require("fennel.utils") +local pack = _863_["pack"] +local unpack = _863_["unpack"] local help = "Usage: 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 try to match Fennel's\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 --keywords K1[,K2...] : Treat these symbols as reserved Lua keywords\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 = {keywords = {}, plugins = {}} -local function pack(...) - local _848_0 = {...} - _848_0["n"] = select("#", ...) - return _848_0 -end local function dosafely(f, ...) local args = {...} local result = nil - local function _849_() + local function _864_() return f(unpack(args)) end - result = pack(xpcall(_849_, fennel.traceback)) + result = pack(xpcall(_864_, fennel.traceback)) if not result[1] then - do end (io.stderr):write((result[2] .. "\n")) + do end (io.stderr):write((tostring(result[2]) .. "\n")) os.exit(1) end return unpack(result, 2, result.n) @@ -6987,25 +7032,25 @@ 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 _854_0, _855_0 = os.execute(table.concat(cmd, " ")) - if (((_854_0 == true) and (_855_0 == "exit")) or (_854_0 == 0)) then + local _869_0, _870_0 = os.execute(table.concat(cmd, " ")) + if (((_869_0 == true) and (_870_0 == "exit")) or (_869_0 == 0)) then return os.exit(0, true) else - local _ = _854_0 + local _ = _869_0 return os.exit(1, true) end end for i = #arg, 1, -1 do - local _857_0 = arg[i] - if (_857_0 == "--lua") then + local _872_0 = arg[i] + if (_872_0 == "--lua") then handle_lua(i) end end local function load_plugin(filename) - if filename:find("%.lua$") then - return dofile(filename) + local opts = {["compiler-env"] = _G, env = "_COMPILER", useMetadata = true} + if (".lua" == filename:sub(-4)) then + return fennel["load-code"](assert(io.open(filename, "rb")):read("*a"), require("fennel.specials")["make-compiler-env"](nil, fennel.scope(), nil, opts), filename)() else - local opts = {["compiler-env"] = _G, env = "_COMPILER", useMetadata = true} return fennel.dofile(filename, opts) end end @@ -7013,58 +7058,55 @@ 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 _860_0 = arg[i] - if (_860_0 == "--no-searcher") then + local _875_0 = arg[i] + if (_875_0 == "--no-searcher") then options["no-searcher"] = true table.remove(arg, i) - elseif (_860_0 == "--indent") then + elseif (_875_0 == "--indent") then options.indent = table.remove(arg, (i + 1)) if (options.indent == "false") then options.indent = false end table.remove(arg, i) - elseif (_860_0 == "--add-package-path") then + elseif (_875_0 == "--add-package-path") then local entry = table.remove(arg, (i + 1)) package.path = (entry .. ";" .. package.path) table.remove(arg, i) - elseif (_860_0 == "--add-package-cpath") then + elseif (_875_0 == "--add-package-cpath") then local entry = table.remove(arg, (i + 1)) package.cpath = (entry .. ";" .. package.cpath) table.remove(arg, i) - elseif (_860_0 == "--add-fennel-path") then + elseif (_875_0 == "--add-fennel-path") then local entry = table.remove(arg, (i + 1)) fennel.path = (entry .. ";" .. fennel.path) table.remove(arg, i) - elseif (_860_0 == "--add-macro-path") then + elseif (_875_0 == "--add-macro-path") then local entry = table.remove(arg, (i + 1)) fennel["macro-path"] = (entry .. ";" .. fennel["macro-path"]) table.remove(arg, i) - elseif (_860_0 == "--load") then + elseif (_875_0 == "--load") then handle_load(i) - elseif (_860_0 == "-l") then + elseif (_875_0 == "-l") then handle_load(i) - elseif (_860_0 == "--no-fennelrc") then + elseif (_875_0 == "--no-fennelrc") then options.fennelrc = false table.remove(arg, i) - elseif (_860_0 == "--correlate") then + elseif (_875_0 == "--correlate") then options.correlate = true table.remove(arg, i) - elseif (_860_0 == "--check-unused-locals") then - options.checkUnusedLocals = true - table.remove(arg, i) - elseif (_860_0 == "--globals") then + elseif (_875_0 == "--globals") then allow_globals(table.remove(arg, (i + 1)), _G) table.remove(arg, i) - elseif (_860_0 == "--globals-only") then + elseif (_875_0 == "--globals-only") then allow_globals(table.remove(arg, (i + 1)), {}) table.remove(arg, i) - elseif (_860_0 == "--require-as-include") then + elseif (_875_0 == "--require-as-include") then options.requireAsInclude = true table.remove(arg, i) - elseif (_860_0 == "--assert-as-repl") then + elseif (_875_0 == "--assert-as-repl") then options.assertAsRepl = true table.remove(arg, i) - elseif (_860_0 == "--skip-include") then + elseif (_875_0 == "--skip-include") then local skip_names = table.remove(arg, (i + 1)) local skip = nil do @@ -7081,32 +7123,32 @@ do end options.skipInclude = skip table.remove(arg, i) - elseif (_860_0 == "--use-bit-lib") then + elseif (_875_0 == "--use-bit-lib") then options.useBitLib = true table.remove(arg, i) - elseif (_860_0 == "--metadata") then + elseif (_875_0 == "--metadata") then options.useMetadata = true table.remove(arg, i) - elseif (_860_0 == "--no-metadata") then + elseif (_875_0 == "--no-metadata") then options.useMetadata = false table.remove(arg, i) - elseif (_860_0 == "--no-compiler-sandbox") then + elseif (_875_0 == "--no-compiler-sandbox") then options["compiler-env"] = _G table.remove(arg, i) - elseif (_860_0 == "--raw-errors") then + elseif (_875_0 == "--raw-errors") then options.unfriendly = true table.remove(arg, i) - elseif (_860_0 == "--plugin") then + elseif (_875_0 == "--plugin") then local plugin = load_plugin(table.remove(arg, (i + 1))) table.insert(options.plugins, 1, plugin) table.remove(arg, i) - elseif (_860_0 == "--keywords") then + elseif (_875_0 == "--keywords") then for keyword in string.gmatch(table.remove(arg, (i + 1)), "[^,]+") do options.keywords[keyword] = true end table.remove(arg, i) else - local _ = _860_0 + local _ = _875_0 if not commands[arg[i]] then options["ignore-options"] = true i = (i + 1) @@ -7145,7 +7187,7 @@ local function repl() 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 + options.fennelrc = load_initfile end if (not readline_3f and ("dumb" ~= os.getenv("TERM"))) then table.insert(welcome, ("Try installing readline via luarocks for a " .. "better repl experience.")) @@ -7154,13 +7196,13 @@ local function repl() return fennel.repl(options) end local function eval(form) - local _870_ + local _885_ if (form == "-") then - _870_ = (io.stdin):read("*a") + _885_ = (io.stdin):read("*a") else - _870_ = form + _885_ = form end - return print(dosafely(fennel.eval, _870_, options)) + return print(dosafely(fennel.eval, _885_, options)) end local function compile(files) for _, filename in ipairs(files) do @@ -7172,17 +7214,17 @@ local function compile(files) f = assert(io.open(filename, "rb")) end do - local _873_0, _874_0 = nil, nil - local function _875_() + local _888_0, _889_0 = nil, nil + local function _890_() return fennel["compile-string"](f:read("*a"), options) end - _873_0, _874_0 = xpcall(_875_, fennel.traceback) - if ((_873_0 == true) and (nil ~= _874_0)) then - local val = _874_0 + _888_0, _889_0 = xpcall(_890_, fennel.traceback) + if ((_888_0 == true) and (nil ~= _889_0)) then + local val = _889_0 print(val) - elseif (true and (nil ~= _874_0)) then - local _0 = _873_0 - local msg = _874_0 + elseif (true and (nil ~= _889_0)) then + local _0 = _888_0 + local msg = _889_0 do end (io.stderr):write((msg .. "\n")) os.exit(1) end @@ -7191,56 +7233,56 @@ local function compile(files) end return nil end -local _877_0 = arg -local function _878_(...) +local _892_0 = arg +local function _893_(...) return (0 == #arg) end -if ((_G.type(_877_0) == "table") and _878_(...)) then +if ((_G.type(_892_0) == "table") and _893_(...)) then return repl() -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "--repl")) then +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--repl")) then return repl() -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "--compile")) then - local files = {select(2, (table.unpack or _G.unpack)(_877_0))} +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--compile")) then + local files = {select(2, (table.unpack or _G.unpack)(_892_0))} return compile(files) -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "-c")) then - local files = {select(2, (table.unpack or _G.unpack)(_877_0))} +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "-c")) then + local files = {select(2, (table.unpack or _G.unpack)(_892_0))} return compile(files) -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "--compile-binary") and (nil ~= _877_0[2]) and (nil ~= _877_0[3]) and (nil ~= _877_0[4]) and (nil ~= _877_0[5])) then - local filename = _877_0[2] - local out = _877_0[3] - local static_lua = _877_0[4] - local lua_include_dir = _877_0[5] - local args = {select(6, (table.unpack or _G.unpack)(_877_0))} +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--compile-binary") and (nil ~= _892_0[2]) and (nil ~= _892_0[3]) and (nil ~= _892_0[4]) and (nil ~= _892_0[5])) then + local filename = _892_0[2] + local out = _892_0[3] + local static_lua = _892_0[4] + local lua_include_dir = _892_0[5] + local args = {select(6, (table.unpack or _G.unpack)(_892_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(_877_0) == "table") and (_877_0[1] == "--compile-binary")) then +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--compile-binary")) then local cmd = (arg[0] or "fennel") return print((require("fennel.binary").help):format(cmd, cmd, cmd)) -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "--eval") and (nil ~= _877_0[2])) then - local form = _877_0[2] +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--eval") and (nil ~= _892_0[2])) then + local form = _892_0[2] return eval(form) -elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "-e") and (nil ~= _877_0[2])) then - local form = _877_0[2] +elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "-e") and (nil ~= _892_0[2])) then + local form = _892_0[2] return eval(form) else - local function _908_(...) - local a = _877_0[1] + local function _923_(...) + local a = _892_0[1] return ((a == "-v") or (a == "--version")) end - if (((_G.type(_877_0) == "table") and (nil ~= _877_0[1])) and _908_(...)) then - local a = _877_0[1] + if (((_G.type(_892_0) == "table") and (nil ~= _892_0[1])) and _923_(...)) then + local a = _892_0[1] return print(fennel["runtime-version"]()) - elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "--help")) then + elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "--help")) then return print(help) - elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "-h")) then + elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "-h")) then return print(help) - elseif ((_G.type(_877_0) == "table") and (_877_0[1] == "-")) then + elseif ((_G.type(_892_0) == "table") and (_892_0[1] == "-")) then return dosafely(fennel.eval, (io.stdin):read("*a")) - elseif ((_G.type(_877_0) == "table") and (nil ~= _877_0[1])) then - local filename = _877_0[1] - local args = {select(2, (table.unpack or _G.unpack)(_877_0))} + elseif ((_G.type(_892_0) == "table") and (nil ~= _892_0[1])) then + local filename = _892_0[1] + local args = {select(2, (table.unpack or _G.unpack)(_892_0))} arg[-2] = arg[-1] arg[-1] = arg[0] arg[0] = table.remove(arg, 1) diff --git a/src/fennel-ls/compiler.fnl b/src/fennel-ls/compiler.fnl index 89e0aa6..7e96d2e 100644 --- a/src/fennel-ls/compiler.fnl +++ b/src/fennel-ls/compiler.fnl @@ -325,7 +325,7 @@ identifiers are declared / referenced in which places." (let [macro-file? (= (file.text:sub 1 24) ";; fennel-ls: macro-file") plugin {:name "fennel-ls" - :versions ["1.4.1" "1.4.2" "1.5.0" "1.5.1" "1.5.2"] + :versions ["1.4.1" "1.4.2" "1.5.0" "1.5.1" "1.5.3" "1.5.4"] : symbol-to-expression : call : destructure