···11-require('impatient').enable_profile()
22-33--- Fennel loader, default one do not work well with NeoVim so there is custom
44--- one
55-_G.fennel = require('fennel')
66-local function fennel_loader(name)
77- local basename = name:gsub('%.', '/')
88- local paths = {"fnl/"..basename..".fnl", "fnl/"..basename.."/init.fnl"}
99-1010- for _, path in ipairs(paths) do
1111- local found = vim.api.nvim_get_runtime_file(path, false)
1212- if #found > 0 then
1313- return function() return fennel.dofile(found[1]) end
1414- end
1515- end
1616-1717- return nil
1818-end
1919-table.insert(package.loaders, 1, fennel_loader)
2020-2121-local fennel_paths = ""
2222-for _, v in pairs(vim.api.nvim_get_runtime_file("fnl/", false)) do
2323- fennel_paths = fennel_paths .. ";" .. v .. "?.fnl"
2424- fennel_paths = fennel_paths .. ";" .. v .. "?/init.fnl"
2525-end
2626-fennel.path = fennel.path .. fennel_paths
2727-2828-require('startup')
+42
vim/.config/nvim/lua/basic.lua
···11+-- Fennel loader, default one do not work well with NeoVim so there is custom
22+-- one
33+_G.fennel = require('fennel')
44+55+-- Load Fennel modules
66+local function fennel_loader(name)
77+ local basename = name:gsub('%.', '/')
88+ local paths = {"fnl/"..basename..".fnl", "fnl/"..basename.."/init.fnl"}
99+1010+ for _, path in ipairs(paths) do
1111+ local found = vim.api.nvim_get_runtime_file(path, false)
1212+ if #found > 0 then
1313+ return function() return fennel.dofile(found[1], {compilerEnv = _G}) end, found[1]
1414+ end
1515+ end
1616+1717+ return nil
1818+end
1919+table.insert(package.loaders, 1, fennel_loader)
2020+2121+-- Load Fennel macros
2222+local function fennel_paths(suffixes)
2323+ local paths = ""
2424+ for _, dir in pairs(vim.api.nvim_get_runtime_file("fnl/", true)) do
2525+ for _, suffix in pairs(suffixes) do
2626+ paths = paths .. ";" .. dir .. "?" .. suffix .. ".fnl"
2727+ end
2828+ end
2929+3030+ return paths
3131+end
3232+fennel["path"] = fennel["path"] .. fennel_paths({"", "/init"})
3333+fennel["macro-path"] = fennel["macro-path"] .. fennel_paths({"", "/macro-init", "/init"})
3434+3535+debug.traceback = fennel.traceback
3636+3737+-- Command-mode Fennel execution
3838+vim.api.nvim_create_user_command('Fennel', function(arg) fennel.eval(arg.args) end, {nargs = '*'})
3939+4040+for _, init in pairs(vim.api.nvim_get_runtime_file("init.fnl", false)) do
4141+ fennel.dofile(init, {compilerEnv = _G})
4242+end
+3555-1606
vim/.config/nvim/lua/fennel.lua
···33 local parser = require("fennel.parser")
44 local compiler = require("fennel.compiler")
55 local specials = require("fennel.specials")
66+ local view = require("fennel.view")
77+ local unpack = (table.unpack or _G.unpack)
68 local function default_read_chunk(parser_state)
77- local function _0_()
99+ local function _620_()
810 if (0 < parser_state["stack-size"]) then
911 return ".."
1012 else
1113 return ">> "
1214 end
1315 end
1414- io.write(_0_())
1616+ io.write(_620_())
1517 io.flush()
1618 local input = io.read()
1719 return (input and (input .. "\n"))
···2123 return io.write("\n")
2224 end
2325 local function default_on_error(errtype, err, lua_source)
2424- local function _1_()
2525- local _0_0 = errtype
2626- if (_0_0 == "Lua Compile") then
2626+ local function _622_()
2727+ local _621_ = errtype
2828+ if (_621_ == "Lua Compile") then
2729 return ("Bad code generated - likely a bug with the compiler:\n" .. "--- Generated Lua Start ---\n" .. lua_source .. "--- Generated Lua End ---\n")
2828- elseif (_0_0 == "Runtime") then
3030+ elseif (_621_ == "Runtime") then
2931 return (compiler.traceback(tostring(err), 4) .. "\n")
3030- else
3131- local _ = _0_0
3232+ elseif true then
3333+ local _ = _621_
3234 return ("%s error: %s\n"):format(errtype, tostring(err))
3535+ else
3636+ return nil
3337 end
3438 end
3535- return io.write(_1_())
3939+ return io.write(_622_())
3640 end
3737- local save_source = table.concat({"local ___i___ = 1", "while true do", " local name, value = debug.getlocal(1, ___i___)", " if(name and name ~= \"___i___\") then", " ___replLocals___[name] = value", " ___i___ = ___i___ + 1", " else break end end"}, "\n")
3838- local function splice_save_locals(env, lua_source)
3939- env.___replLocals___ = (env.___replLocals___ or {})
4141+ local save_source = " ___replLocals___['%s'] = %s"
4242+ local function splice_save_locals(env, lua_source, scope)
4043 local spliced_source = {}
4144 local bind = "local %s = ___replLocals___['%s']"
4245 for line in lua_source:gmatch("([^\n]+)\n?") do
···4649 table.insert(spliced_source, 1, bind:format(name, name))
4750 end
4851 if ((1 < #spliced_source) and (spliced_source[#spliced_source]):match("^ *return .*$")) then
4949- table.insert(spliced_source, #spliced_source, save_source)
5252+ for _, name in pairs(scope.manglings) do
5353+ table.insert(spliced_source, #spliced_source, save_source:format(name, name))
5454+ end
5555+ else
5056 end
5157 return table.concat(spliced_source, "\n")
5258 end
5959+ local function completer(env, scope, text)
6060+ local max_items = 2000
6161+ local seen = {}
6262+ local matches = {}
6363+ local input_fragment = text:gsub(".*[%s)(]+", "")
6464+ local stop_looking_3f = false
6565+ local function add_partials(input, tbl, prefix)
6666+ local scope_first_3f = ((tbl == env) or (tbl == env.___replLocals___))
6767+ local tbl_14_auto = matches
6868+ local i_15_auto = #tbl_14_auto
6969+ local function _625_()
7070+ if scope_first_3f then
7171+ return scope.manglings
7272+ else
7373+ return tbl
7474+ end
7575+ end
7676+ for k, is_mangled in utils.allpairs(_625_()) do
7777+ if (max_items <= #matches) then break end
7878+ local val_16_auto
7979+ do
8080+ local lookup_k
8181+ if scope_first_3f then
8282+ lookup_k = is_mangled
8383+ else
8484+ lookup_k = k
8585+ end
8686+ if ((type(k) == "string") and (input == k:sub(0, #input)) and not seen[k] and ((":" ~= prefix:sub(-1)) or ("function" == type(tbl[lookup_k])))) then
8787+ seen[k] = true
8888+ val_16_auto = (prefix .. k)
8989+ else
9090+ val_16_auto = nil
9191+ end
9292+ end
9393+ if (nil ~= val_16_auto) then
9494+ i_15_auto = (i_15_auto + 1)
9595+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
9696+ else
9797+ end
9898+ end
9999+ return tbl_14_auto
100100+ end
101101+ local function descend(input, tbl, prefix, add_matches, method_3f)
102102+ local splitter
103103+ if method_3f then
104104+ splitter = "^([^:]+):(.*)"
105105+ else
106106+ splitter = "^([^.]+)%.(.*)"
107107+ end
108108+ local head, tail = input:match(splitter)
109109+ local raw_head = (scope.manglings[head] or head)
110110+ if (type(tbl[raw_head]) == "table") then
111111+ stop_looking_3f = true
112112+ if method_3f then
113113+ return add_partials(tail, tbl[raw_head], (prefix .. head .. ":"))
114114+ else
115115+ return add_matches(tail, tbl[raw_head], (prefix .. head))
116116+ end
117117+ else
118118+ return nil
119119+ end
120120+ end
121121+ local function add_matches(input, tbl, prefix)
122122+ local prefix0
123123+ if prefix then
124124+ prefix0 = (prefix .. ".")
125125+ else
126126+ prefix0 = ""
127127+ end
128128+ if (not input:find("%.") and input:find(":")) then
129129+ return descend(input, tbl, prefix0, add_matches, true)
130130+ elseif not input:find("%.") then
131131+ return add_partials(input, tbl, prefix0)
132132+ else
133133+ return descend(input, tbl, prefix0, add_matches, false)
134134+ end
135135+ end
136136+ for _, source in ipairs({scope.specials, scope.macros, (env.___replLocals___ or {}), env, env._G}) do
137137+ if stop_looking_3f then break end
138138+ add_matches(input_fragment, source)
139139+ end
140140+ return matches
141141+ end
53142 local commands = {}
54143 local function command_3f(input)
55144 return input:match("^%s*,")
56145 end
57146 local function command_docs()
5858- local _0_
147147+ local _634_
59148 do
6060- local tbl_0_ = {}
149149+ local tbl_14_auto = {}
150150+ local i_15_auto = #tbl_14_auto
61151 for name, f in pairs(commands) do
6262- tbl_0_[(#tbl_0_ + 1)] = (" ,%s - %s"):format(name, ((compiler.metadata):get(f, "fnl/docstring") or "undocumented"))
152152+ local val_16_auto = (" ,%s - %s"):format(name, ((compiler.metadata):get(f, "fnl/docstring") or "undocumented"))
153153+ if (nil ~= val_16_auto) then
154154+ i_15_auto = (i_15_auto + 1)
155155+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
156156+ else
157157+ end
63158 end
6464- _0_ = tbl_0_
159159+ _634_ = tbl_14_auto
65160 end
6666- return table.concat(_0_, "\n")
161161+ return table.concat(_634_, "\n")
67162 end
68163 commands.help = function(_, _0, on_values)
6969- return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,exit - Leave the repl.\n\nUse (doc something) to see descriptions for individual macros and special forms.\n\nFor more information about the language, see https://fennel-lang.org/reference")})
164164+ return on_values({("Welcome to Fennel.\nThis is the REPL where you can enter code to be evaluated.\nYou can also run these repl commands:\n\n" .. command_docs() .. "\n ,exit - Leave the repl.\n\nUse ,doc something to see descriptions for individual macros and special forms.\n\nFor more information about the language, see https://fennel-lang.org/reference")})
70165 end
71166 do end (compiler.metadata):set(commands.help, "fnl/docstring", "Show this message.")
72167 local function reload(module_name, env, on_values, on_error)
7373- local _0_0, _1_0 = pcall(specials["load-code"]("return require(...)", env), module_name)
7474- if ((_0_0 == true) and (nil ~= _1_0)) then
7575- local old = _1_0
7676- local _ = nil
168168+ local _636_, _637_ = pcall(specials["load-code"]("return require(...)", env), module_name)
169169+ if ((_636_ == true) and (nil ~= _637_)) then
170170+ local old = _637_
171171+ local _
77172 package.loaded[module_name] = nil
78173 _ = nil
79174 local ok, new = pcall(require, module_name)
8080- local new0 = nil
175175+ local new0
81176 if not ok then
82177 on_values({new})
83178 new0 = old
84179 else
85180 new0 = new
86181 end
182182+ specials["macro-loaded"][module_name] = nil
87183 if ((type(old) == "table") and (type(new0) == "table")) then
88184 for k, v in pairs(new0) do
89185 old[k] = v
90186 end
91187 for k in pairs(old) do
9292- if (nil == new0[k]) then
188188+ if (nil == (new0)[k]) then
93189 old[k] = nil
190190+ else
94191 end
95192 end
96193 package.loaded[module_name] = old
194194+ else
97195 end
98196 return on_values({"ok"})
9999- elseif ((_0_0 == false) and (nil ~= _1_0)) then
100100- local msg = _1_0
101101- local function _3_()
102102- local _2_0 = msg:gsub("\n.*", "")
103103- return _2_0
197197+ elseif ((_636_ == false) and (nil ~= _637_)) then
198198+ local msg = _637_
199199+ if (specials["macro-loaded"])[module_name] then
200200+ specials["macro-loaded"][module_name] = nil
201201+ return nil
202202+ else
203203+ local function _642_()
204204+ local _641_ = msg:gsub("\n.*", "")
205205+ return _641_
206206+ end
207207+ return on_error("Runtime", _642_())
104208 end
105105- return on_error("Runtime", _3_())
209209+ else
210210+ return nil
211211+ end
212212+ end
213213+ local function run_command(read, on_error, f)
214214+ local _645_, _646_, _647_ = pcall(read)
215215+ if ((_645_ == true) and (_646_ == true) and (nil ~= _647_)) then
216216+ local val = _647_
217217+ return f(val)
218218+ elseif (_645_ == false) then
219219+ return on_error("Parse", "Couldn't parse input.")
220220+ else
221221+ return nil
106222 end
107223 end
108224 commands.reload = function(env, read, on_values, on_error)
109109- local _0_0, _1_0, _2_0 = pcall(read)
110110- if ((_0_0 == true) and (_1_0 == true) and (nil ~= _2_0)) then
111111- local module_sym = _2_0
112112- return reload(tostring(module_sym), env, on_values, on_error)
113113- elseif ((_0_0 == false) and true and true) then
114114- local _3fparse_ok = _1_0
115115- local _3fmsg = _2_0
116116- return on_error("Parse", (_3fmsg or _3fparse_ok))
225225+ local function _649_(_241)
226226+ return reload(tostring(_241), env, on_values, on_error)
117227 end
228228+ return run_command(read, on_error, _649_)
118229 end
119230 do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.")
120231 commands.reset = function(env, _, on_values)
···122233 return on_values({"ok"})
123234 end
124235 do end (compiler.metadata):set(commands.reset, "fnl/docstring", "Erase all repl-local scope.")
125125- local function load_plugin_commands()
126126- if (utils.root and utils.root.options and utils.root.options.plugins) then
127127- for _, plugin in ipairs(utils.root.options.plugins) do
128128- for name, f in pairs(plugin) do
129129- local _0_0 = name:match("^repl%-command%-(.*)")
130130- if (nil ~= _0_0) then
131131- local cmd_name = _0_0
132132- commands[cmd_name] = (commands[cmd_name] or f)
236236+ commands.complete = function(env, read, on_values, on_error, scope, chars)
237237+ local function _650_()
238238+ return on_values(completer(env, scope, string.char(unpack(chars)):gsub(",complete +", ""):sub(1, -2)))
239239+ end
240240+ return run_command(read, on_error, _650_)
241241+ end
242242+ do end (compiler.metadata):set(commands.complete, "fnl/docstring", "Print all possible completions for a given input symbol.")
243243+ local function apropos_2a(pattern, tbl, prefix, seen, names)
244244+ for name, subtbl in pairs(tbl) do
245245+ if (("string" == type(name)) and (package ~= subtbl)) then
246246+ local _651_ = type(subtbl)
247247+ if (_651_ == "function") then
248248+ if ((prefix .. name)):match(pattern) then
249249+ table.insert(names, (prefix .. name))
250250+ else
251251+ end
252252+ elseif (_651_ == "table") then
253253+ if not seen[subtbl] then
254254+ local _654_
255255+ do
256256+ local _653_ = seen
257257+ _653_[subtbl] = true
258258+ _654_ = _653_
259259+ end
260260+ apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _654_, names)
261261+ else
262262+ end
263263+ else
264264+ end
265265+ else
266266+ end
267267+ end
268268+ return names
269269+ end
270270+ local function apropos(pattern)
271271+ local names = apropos_2a(pattern, package.loaded, "", {}, {})
272272+ local tbl_14_auto = {}
273273+ local i_15_auto = #tbl_14_auto
274274+ for _, name in ipairs(names) do
275275+ local val_16_auto = name:gsub("^_G%.", "")
276276+ if (nil ~= val_16_auto) then
277277+ i_15_auto = (i_15_auto + 1)
278278+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
279279+ else
280280+ end
281281+ end
282282+ return tbl_14_auto
283283+ end
284284+ commands.apropos = function(_env, read, on_values, on_error, _scope)
285285+ local function _659_(_241)
286286+ return on_values(apropos(tostring(_241)))
287287+ end
288288+ return run_command(read, on_error, _659_)
289289+ end
290290+ do end (compiler.metadata):set(commands.apropos, "fnl/docstring", "Print all functions matching a pattern in all loaded modules.")
291291+ local function apropos_follow_path(path)
292292+ local paths
293293+ do
294294+ local tbl_14_auto = {}
295295+ local i_15_auto = #tbl_14_auto
296296+ for p in path:gmatch("[^%.]+") do
297297+ local val_16_auto = p
298298+ if (nil ~= val_16_auto) then
299299+ i_15_auto = (i_15_auto + 1)
300300+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
301301+ else
302302+ end
303303+ end
304304+ paths = tbl_14_auto
305305+ end
306306+ local tgt = package.loaded
307307+ for _, path0 in ipairs(paths) do
308308+ if (nil == tgt) then break end
309309+ local _662_
310310+ do
311311+ local _661_ = path0:gsub("%/", ".")
312312+ _662_ = _661_
313313+ end
314314+ tgt = tgt[_662_]
315315+ end
316316+ return tgt
317317+ end
318318+ local function apropos_doc(pattern)
319319+ local tbl_14_auto = {}
320320+ local i_15_auto = #tbl_14_auto
321321+ for _, path in ipairs(apropos(".*")) do
322322+ local val_16_auto
323323+ do
324324+ local tgt = apropos_follow_path(path)
325325+ if ("function" == type(tgt)) then
326326+ local _663_ = (compiler.metadata):get(tgt, "fnl/docstring")
327327+ if (nil ~= _663_) then
328328+ local docstr = _663_
329329+ val_16_auto = (docstr:match(pattern) and path)
330330+ else
331331+ val_16_auto = nil
133332 end
333333+ else
334334+ val_16_auto = nil
134335 end
135336 end
337337+ if (nil ~= val_16_auto) then
338338+ i_15_auto = (i_15_auto + 1)
339339+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
340340+ else
341341+ end
342342+ end
343343+ return tbl_14_auto
344344+ end
345345+ commands["apropos-doc"] = function(_env, read, on_values, on_error, _scope)
346346+ local function _667_(_241)
347347+ return on_values(apropos_doc(tostring(_241)))
348348+ end
349349+ return run_command(read, on_error, _667_)
350350+ end
351351+ do end (compiler.metadata):set(commands["apropos-doc"], "fnl/docstring", "Print all functions that match the pattern in their docs")
352352+ local function apropos_show_docs(on_values, pattern)
353353+ for _, path in ipairs(apropos(pattern)) do
354354+ local tgt = apropos_follow_path(path)
355355+ if (("function" == type(tgt)) and (compiler.metadata):get(tgt, "fnl/docstring")) then
356356+ on_values(specials.doc(tgt, path))
357357+ on_values()
358358+ else
359359+ end
360360+ end
361361+ return nil
362362+ end
363363+ commands["apropos-show-docs"] = function(_env, read, on_values, on_error)
364364+ local function _669_(_241)
365365+ return apropos_show_docs(on_values, tostring(_241))
366366+ end
367367+ return run_command(read, on_error, _669_)
368368+ end
369369+ do end (compiler.metadata):set(commands["apropos-show-docs"], "fnl/docstring", "Print all documentations matching a pattern in function name")
370370+ local function resolve(identifier, _670_, scope)
371371+ local _arg_671_ = _670_
372372+ local ___replLocals___ = _arg_671_["___replLocals___"]
373373+ local env = _arg_671_
374374+ local e
375375+ local function _672_(_241, _242)
376376+ return (___replLocals___[_242] or env[_242])
377377+ end
378378+ e = setmetatable({}, {__index = _672_})
379379+ local _673_, _674_ = pcall(compiler["compile-string"], tostring(identifier), {scope = scope})
380380+ if ((_673_ == true) and (nil ~= _674_)) then
381381+ local code = _674_
382382+ return specials["load-code"](code, e)()
383383+ else
136384 return nil
137385 end
138386 end
139139- local function run_command(input, read, loop, env, on_values, on_error)
140140- load_plugin_commands()
387387+ commands.find = function(env, read, on_values, on_error, scope)
388388+ local function _676_(_241)
389389+ local _677_
390390+ do
391391+ local _678_ = utils["sym?"](_241)
392392+ if (nil ~= _678_) then
393393+ local _679_ = resolve(_678_, env, scope)
394394+ if (nil ~= _679_) then
395395+ _677_ = debug.getinfo(_679_)
396396+ else
397397+ _677_ = _679_
398398+ end
399399+ else
400400+ _677_ = _678_
401401+ end
402402+ end
403403+ if ((_G.type(_677_) == "table") and ((_677_).what == "Lua") and (nil ~= (_677_).source) and (nil ~= (_677_).linedefined) and (nil ~= (_677_).short_src)) then
404404+ local source = (_677_).source
405405+ local line = (_677_).linedefined
406406+ local src = (_677_).short_src
407407+ local fnlsrc
408408+ do
409409+ local t_682_ = compiler.sourcemap
410410+ if (nil ~= t_682_) then
411411+ t_682_ = (t_682_)[source]
412412+ else
413413+ end
414414+ if (nil ~= t_682_) then
415415+ t_682_ = (t_682_)[line]
416416+ else
417417+ end
418418+ if (nil ~= t_682_) then
419419+ t_682_ = (t_682_)[2]
420420+ else
421421+ end
422422+ fnlsrc = t_682_
423423+ end
424424+ return on_values({string.format("%s:%s", src, (fnlsrc or line))})
425425+ elseif (_677_ == nil) then
426426+ return on_error("Repl", "Unknown value")
427427+ elseif true then
428428+ local _ = _677_
429429+ return on_error("Repl", "No source info")
430430+ else
431431+ return nil
432432+ end
433433+ end
434434+ return run_command(read, on_error, _676_)
435435+ end
436436+ do end (compiler.metadata):set(commands.find, "fnl/docstring", "Print the filename and line number for a given function")
437437+ commands.doc = function(env, read, on_values, on_error, scope)
438438+ local function _687_(_241)
439439+ local name = tostring(_241)
440440+ local path = (utils["multi-sym?"](name) or {name})
441441+ local ok_3f, target = nil, nil
442442+ local function _688_()
443443+ return (utils["get-in"](scope.specials, path) or utils["get-in"](scope.macros, path) or resolve(name, env, scope))
444444+ end
445445+ ok_3f, target = pcall(_688_)
446446+ if ok_3f then
447447+ return on_values({specials.doc(target, name)})
448448+ else
449449+ return on_error("Repl", "Could not resolve value for docstring lookup")
450450+ end
451451+ end
452452+ return run_command(read, on_error, _687_)
453453+ end
454454+ do end (compiler.metadata):set(commands.doc, "fnl/docstring", "Print the docstring and arglist for a function, macro, or special form.")
455455+ commands.compile = function(env, read, on_values, on_error, scope)
456456+ local function _690_(_241)
457457+ local allowedGlobals = specials["current-global-names"](env)
458458+ local ok_3f, result = pcall(compiler.compile, _241, {env = env, scope = scope, allowedGlobals = allowedGlobals})
459459+ if ok_3f then
460460+ return on_values({result})
461461+ else
462462+ return on_error("Repl", ("Error compiling expression: " .. result))
463463+ end
464464+ end
465465+ return run_command(read, on_error, _690_)
466466+ end
467467+ do end (compiler.metadata):set(commands.compile, "fnl/docstring", "compiles the expression into lua and prints the result.")
468468+ local function load_plugin_commands(plugins)
469469+ for _, plugin in ipairs((plugins or {})) do
470470+ for name, f in pairs(plugin) do
471471+ local _692_ = name:match("^repl%-command%-(.*)")
472472+ if (nil ~= _692_) then
473473+ local cmd_name = _692_
474474+ commands[cmd_name] = (commands[cmd_name] or f)
475475+ else
476476+ end
477477+ end
478478+ end
479479+ return nil
480480+ end
481481+ local function run_command_loop(input, read, loop, env, on_values, on_error, scope, chars)
141482 local command_name = input:match(",([^%s/]+)")
142483 do
143143- local _0_0 = commands[command_name]
144144- if (nil ~= _0_0) then
145145- local command = _0_0
146146- command(env, read, on_values, on_error)
147147- else
148148- local _ = _0_0
484484+ local _694_ = commands[command_name]
485485+ if (nil ~= _694_) then
486486+ local command = _694_
487487+ command(env, read, on_values, on_error, scope, chars)
488488+ elseif true then
489489+ local _ = _694_
149490 if ("exit" ~= command_name) then
150491 on_values({"Unknown command", command_name})
492492+ else
151493 end
494494+ else
152495 end
153496 end
154497 if ("exit" ~= command_name) then
155498 return loop()
499499+ else
500500+ return nil
156501 end
157502 end
158158- local function completer(env, scope, text)
159159- local matches = {}
160160- local input_fragment = text:gsub(".*[%s)(]+", "")
161161- local function add_partials(input, tbl, prefix)
162162- for k in utils.allpairs(tbl) do
163163- local k0 = nil
164164- if ((tbl == env) or (tbl == env.___replLocals___)) then
165165- k0 = scope.unmanglings[k]
503503+ local function try_readline_21(opts, ok, readline)
504504+ if ok then
505505+ if readline.set_readline_name then
506506+ readline.set_readline_name("fennel")
507507+ else
508508+ end
509509+ do
510510+ local rl_opts
511511+ do
512512+ local tbl_11_auto = {keeplines = 1000, histfile = ""}
513513+ for k, v in pairs(readline.set_options({})) do
514514+ local _699_, _700_ = k, v
515515+ if ((nil ~= _699_) and (nil ~= _700_)) then
516516+ local k_12_auto = _699_
517517+ local v_13_auto = _700_
518518+ tbl_11_auto[k_12_auto] = v_13_auto
519519+ else
520520+ end
521521+ end
522522+ rl_opts = tbl_11_auto
523523+ end
524524+ readline.set_options(rl_opts)
525525+ end
526526+ opts.readChunk = function(parser_state)
527527+ local prompt
528528+ if (0 < parser_state["stack-size"]) then
529529+ prompt = ".. "
166530 else
167167- k0 = k
531531+ prompt = ">> "
168532 end
169169- if ((#matches < 2000) and (type(k0) == "string") and (input == k0:sub(0, #input))) then
170170- table.insert(matches, (prefix .. k0))
533533+ local str = readline.readline(prompt)
534534+ if str then
535535+ return (str .. "\n")
536536+ else
537537+ return nil
171538 end
172539 end
173173- return nil
174174- end
175175- local function add_matches(input, tbl, prefix)
176176- local prefix0 = nil
177177- if prefix then
178178- prefix0 = (prefix .. ".")
179179- else
180180- prefix0 = ""
540540+ local completer0 = nil
541541+ opts.registerCompleter = function(repl_completer)
542542+ completer0 = repl_completer
543543+ return nil
181544 end
182182- if not input:find("%.") then
183183- return add_partials(input, tbl, prefix0)
184184- else
185185- local head, tail = input:match("^([^.]+)%.(.*)")
186186- local raw_head = nil
187187- if ((tbl == env) or (tbl == env.___replLocals___)) then
188188- raw_head = scope.manglings[head]
545545+ local function repl_completer(text, from, to)
546546+ if completer0 then
547547+ readline.set_completion_append_character("")
548548+ return completer0(text:sub(from, to))
189549 else
190190- raw_head = head
191191- end
192192- if (type(tbl[raw_head]) == "table") then
193193- return add_matches(tail, tbl[raw_head], (prefix0 .. head))
550550+ return {}
194551 end
195552 end
553553+ readline.set_complete_function(repl_completer)
554554+ return readline
555555+ else
556556+ return nil
196557 end
197197- add_matches(input_fragment, (scope.specials or {}))
198198- add_matches(input_fragment, (scope.macros or {}))
199199- add_matches(input_fragment, (env.___replLocals___ or {}))
200200- add_matches(input_fragment, env)
201201- add_matches(input_fragment, (env._ENV or env._G or {}))
202202- return matches
558558+ end
559559+ local function should_use_readline_3f(opts)
560560+ return (("dumb" ~= os.getenv("TERM")) and not opts.readChunk and not opts.registerCompleter)
203561 end
204204- local function repl(options)
562562+ local function repl(_3foptions)
205563 local old_root_options = utils.root.options
206206- local env = nil
207207- if options.env then
208208- env = specials["wrap-env"](options.env)
209209- else
210210- env = setmetatable({}, {__index = (rawget(_G, "_ENV") or _G)})
211211- end
212212- local save_locals_3f = ((options.saveLocals ~= false) and env.debug and env.debug.getlocal)
213213- local opts = {}
214214- local _ = nil
215215- for k, v in pairs(options) do
216216- opts[k] = v
217217- end
218218- _ = nil
564564+ local opts = ((_3foptions and utils.copy(_3foptions)) or {})
565565+ local readline = (should_use_readline_3f(opts) and try_readline_21(opts, pcall(require, "readline")))
566566+ local env = specials["wrap-env"]((opts.env or rawget(_G, "_ENV") or _G))
567567+ local save_locals_3f = (opts.saveLocals ~= false)
219568 local read_chunk = (opts.readChunk or default_read_chunk)
220569 local on_values = (opts.onValues or default_on_values)
221570 local on_error = (opts.onError or default_on_error)
222222- local pp = (opts.pp or tostring)
571571+ local pp = (opts.pp or view)
223572 local byte_stream, clear_stream = parser.granulate(read_chunk)
224573 local chars = {}
225574 local read, reset = nil, nil
226226- local function _1_(parser_state)
575575+ local function _706_(parser_state)
227576 local c = byte_stream(parser_state)
228577 table.insert(chars, c)
229578 return c
230579 end
231231- read, reset = parser.parser(_1_)
232232- local scope = compiler["make-scope"]()
233233- opts.useMetadata = (options.useMetadata ~= false)
580580+ read, reset = parser.parser(_706_)
581581+ opts.env, opts.scope = env, compiler["make-scope"]()
582582+ opts.useMetadata = (opts.useMetadata ~= false)
234583 if (opts.allowedGlobals == nil) then
235235- opts.allowedGlobals = specials["current-global-names"](opts.env)
584584+ opts.allowedGlobals = specials["current-global-names"](env)
585585+ else
236586 end
237587 if opts.registerCompleter then
238238- local function _3_(...)
239239- return completer(env, scope, ...)
588588+ local function _710_()
589589+ local _708_ = env
590590+ local _709_ = opts.scope
591591+ local function _711_(...)
592592+ return completer(_708_, _709_, ...)
593593+ end
594594+ return _711_
240595 end
241241- opts.registerCompleter(_3_)
596596+ opts.registerCompleter(_710_())
597597+ else
598598+ end
599599+ load_plugin_commands(opts.plugins)
600600+ if save_locals_3f then
601601+ local function newindex(t, k, v)
602602+ if opts.scope.unmanglings[k] then
603603+ return rawset(t, k, v)
604604+ else
605605+ return nil
606606+ end
607607+ end
608608+ env.___replLocals___ = setmetatable({}, {__newindex = newindex})
609609+ else
242610 end
243611 local function print_values(...)
244612 local vals = {...}
···253621 for k in pairs(chars) do
254622 chars[k] = nil
255623 end
256256- local ok, parse_ok_3f, x = pcall(read)
257257- local src_string = string.char((table.unpack or _G.unpack)(chars))
258258- utils.root.options = opts
624624+ reset()
625625+ local ok, not_eof_3f, x = pcall(read)
626626+ local src_string = string.char(unpack(chars))
259627 if not ok then
260260- on_error("Parse", parse_ok_3f)
628628+ on_error("Parse", not_eof_3f)
261629 clear_stream()
262262- reset()
263630 return loop()
264631 elseif command_3f(src_string) then
265265- return run_command(src_string, read, loop, env, on_values, on_error)
632632+ return run_command_loop(src_string, read, loop, env, on_values, on_error, opts.scope, chars)
266633 else
267267- if parse_ok_3f then
634634+ if not_eof_3f then
268635 do
269269- local _4_0, _5_0 = pcall(compiler.compile, x, {["assert-compile"] = opts["assert-compile"], ["parse-error"] = opts["parse-error"], correlate = opts.correlate, moduleName = opts.moduleName, scope = scope, source = src_string, useMetadata = opts.useMetadata})
270270- if ((_4_0 == false) and (nil ~= _5_0)) then
271271- local msg = _5_0
636636+ local _715_, _716_ = nil, nil
637637+ local function _718_()
638638+ local _717_ = opts
639639+ _717_["source"] = src_string
640640+ return _717_
641641+ end
642642+ _715_, _716_ = pcall(compiler.compile, x, _718_())
643643+ if ((_715_ == false) and (nil ~= _716_)) then
644644+ local msg = _716_
272645 clear_stream()
273646 on_error("Compile", msg)
274274- elseif ((_4_0 == true) and (nil ~= _5_0)) then
275275- local src = _5_0
276276- local src0 = nil
647647+ elseif ((_715_ == true) and (nil ~= _716_)) then
648648+ local src = _716_
649649+ local src0
277650 if save_locals_3f then
278278- src0 = splice_save_locals(env, src)
651651+ src0 = splice_save_locals(env, src, opts.scope)
279652 else
280653 src0 = src
281654 end
282282- local _7_0, _8_0 = pcall(specials["load-code"], src0, env)
283283- if ((_7_0 == false) and (nil ~= _8_0)) then
284284- local msg = _8_0
655655+ local _720_, _721_ = pcall(specials["load-code"], src0, env)
656656+ if ((_720_ == false) and (nil ~= _721_)) then
657657+ local msg = _721_
285658 clear_stream()
286659 on_error("Lua Compile", msg, src0)
287287- elseif (true and (nil ~= _8_0)) then
288288- local _0 = _7_0
289289- local chunk = _8_0
290290- local function _9_()
660660+ elseif (true and (nil ~= _721_)) then
661661+ local _ = _720_
662662+ local chunk = _721_
663663+ local function _722_()
291664 return print_values(chunk())
292665 end
293293- local function _10_(...)
294294- return on_error("Runtime", ...)
666666+ local function _723_()
667667+ local function _724_(...)
668668+ return on_error("Runtime", ...)
669669+ end
670670+ return _724_
295671 end
296296- xpcall(_9_, _10_)
672672+ xpcall(_722_, _723_())
673673+ else
297674 end
675675+ else
298676 end
299677 end
300678 utils.root.options = old_root_options
301679 return loop()
302302- end
303303- end
304304- end
305305- return loop()
306306- end
307307- return repl
308308-end
309309-package.preload["fennel.view"] = package.preload["fennel.view"] or function(...)
310310- local type_order = {["function"] = 5, boolean = 2, number = 1, string = 3, table = 4, thread = 7, userdata = 6}
311311- local function sort_keys(_0_0, _1_0)
312312- local _1_ = _0_0
313313- local a = _1_[1]
314314- local _2_ = _1_0
315315- local b = _2_[1]
316316- local ta = type(a)
317317- local tb = type(b)
318318- if ((ta == tb) and ((ta == "string") or (ta == "number"))) then
319319- return (a < b)
320320- else
321321- local dta = type_order[ta]
322322- local dtb = type_order[tb]
323323- if (dta and dtb) then
324324- return (dta < dtb)
325325- elseif dta then
326326- return true
327327- elseif dtb then
328328- return false
329329- else
330330- return (ta < tb)
331331- end
332332- end
333333- end
334334- local function table_kv_pairs(t)
335335- local assoc_3f = false
336336- local kv = {}
337337- local insert = table.insert
338338- for k, v in pairs(t) do
339339- if (type(k) ~= "number") then
340340- assoc_3f = true
341341- end
342342- insert(kv, {k, v})
343343- end
344344- table.sort(kv, sort_keys)
345345- if (#kv == 0) then
346346- return kv, "empty"
347347- else
348348- local function _2_()
349349- if assoc_3f then
350350- return "table"
351680 else
352352- return "seq"
353353- end
354354- end
355355- return kv, _2_()
356356- end
357357- end
358358- local function count_table_appearances(t, appearances)
359359- if (type(t) == "table") then
360360- if not appearances[t] then
361361- appearances[t] = 1
362362- for k, v in pairs(t) do
363363- count_table_appearances(k, appearances)
364364- count_table_appearances(v, appearances)
681681+ return nil
365682 end
366366- else
367367- appearances[t] = ((appearances[t] or 0) + 1)
368683 end
369684 end
370370- return appearances
371371- end
372372- local function save_table(t, seen)
373373- local seen0 = (seen or {len = 0})
374374- local id = (seen0.len + 1)
375375- if not seen0[t] then
376376- seen0[t] = id
377377- seen0.len = id
378378- end
379379- return seen0
380380- end
381381- local function detect_cycle(t, seen)
382382- local seen0 = (seen or {})
383383- seen0[t] = true
384384- for k, v in pairs(t) do
385385- if ((type(k) == "table") and (seen0[k] or detect_cycle(k, seen0))) then
386386- return true
387387- end
388388- if ((type(v) == "table") and (seen0[v] or detect_cycle(v, seen0))) then
389389- return true
390390- end
391391- end
392392- return nil
393393- end
394394- local function visible_cycle_3f(t, options)
395395- return (options["detect-cycles?"] and detect_cycle(t) and save_table(t, options.seen) and (1 < (options.appearances[t] or 0)))
396396- end
397397- local function table_indent(t, indent, id)
398398- local opener_length = nil
399399- if id then
400400- opener_length = (#tostring(id) + 2)
685685+ loop()
686686+ if readline then
687687+ return readline.save_history()
401688 else
402402- opener_length = 1
689689+ return nil
403690 end
404404- return (indent + opener_length)
405691 end
406406- local pp = {}
407407- local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix)
408408- local indent_str = ("\n" .. string.rep(" ", indent))
409409- local open = nil
410410- local function _2_()
411411- if ("seq" == table_type) then
412412- return "["
413413- else
414414- return "{"
415415- end
416416- end
417417- open = ((prefix or "") .. _2_())
418418- local close = nil
419419- if ("seq" == table_type) then
420420- close = "]"
421421- else
422422- close = "}"
423423- end
424424- local oneline = (open .. table.concat(elements, " ") .. close)
425425- local _4_
426426- if (table_type == "seq") then
427427- _4_ = options["sequential-length"]
428428- else
429429- _4_ = options["associative-length"]
430430- end
431431- if (not options["one-line?"] and (multiline_3f or (#elements > _4_) or ((indent + #oneline) > options["line-length"]))) then
432432- return (open .. table.concat(elements, indent_str) .. close)
433433- else
434434- return oneline
435435- end
436436- end
437437- local function pp_associative(t, kv, options, indent, key_3f)
438438- local multiline_3f = false
439439- local id = options.seen[t]
440440- if (options.level >= options.depth) then
441441- return "{...}"
442442- elseif (id and options["detect-cycles?"]) then
443443- return ("@" .. id .. "{...}")
444444- else
445445- local visible_cycle_3f0 = visible_cycle_3f(t, options)
446446- local id0 = (visible_cycle_3f0 and options.seen[t])
447447- local indent0 = table_indent(t, indent, id0)
448448- local slength = nil
449449- local function _3_()
450450- local _2_0 = rawget(_G, "utf8")
451451- if _2_0 then
452452- return _2_0.len
453453- else
454454- return _2_0
455455- end
456456- end
457457- local function _4_(_241)
458458- return #_241
459459- end
460460- slength = ((options["utf8?"] and _3_()) or _4_)
461461- local prefix = nil
462462- if visible_cycle_3f0 then
463463- prefix = ("@" .. id0)
464464- else
465465- prefix = ""
466466- end
467467- local elements = nil
468468- do
469469- local tbl_0_ = {}
470470- for _, _6_0 in pairs(kv) do
471471- local _7_ = _6_0
472472- local k = _7_[1]
473473- local v = _7_[2]
474474- local _8_
475475- do
476476- local k0 = pp.pp(k, options, (indent0 + 1), true)
477477- local v0 = pp.pp(v, options, (indent0 + slength(k0) + 1))
478478- multiline_3f = (multiline_3f or k0:find("\n") or v0:find("\n"))
479479- _8_ = (k0 .. " " .. v0)
480480- end
481481- tbl_0_[(#tbl_0_ + 1)] = _8_
482482- end
483483- elements = tbl_0_
484484- end
485485- return concat_table_lines(elements, options, multiline_3f, indent0, "table", prefix)
486486- end
487487- end
488488- local function pp_sequence(t, kv, options, indent)
489489- local multiline_3f = false
490490- local id = options.seen[t]
491491- if (options.level >= options.depth) then
492492- return "[...]"
493493- elseif (id and options["detect-cycles?"]) then
494494- return ("@" .. id .. "[...]")
495495- else
496496- local visible_cycle_3f0 = visible_cycle_3f(t, options)
497497- local id0 = (visible_cycle_3f0 and options.seen[t])
498498- local indent0 = table_indent(t, indent, id0)
499499- local prefix = nil
500500- if visible_cycle_3f0 then
501501- prefix = ("@" .. id0)
502502- else
503503- prefix = ""
504504- end
505505- local elements = nil
506506- do
507507- local tbl_0_ = {}
508508- for _, _3_0 in pairs(kv) do
509509- local _4_ = _3_0
510510- local _0 = _4_[1]
511511- local v = _4_[2]
512512- local _5_
513513- do
514514- local v0 = pp.pp(v, options, indent0)
515515- multiline_3f = (multiline_3f or v0:find("\n"))
516516- _5_ = v0
517517- end
518518- tbl_0_[(#tbl_0_ + 1)] = _5_
519519- end
520520- elements = tbl_0_
521521- end
522522- return concat_table_lines(elements, options, multiline_3f, indent0, "seq", prefix)
523523- end
524524- end
525525- local function concat_lines(lines, options, indent, force_multi_line_3f)
526526- if (#lines == 0) then
527527- if options["empty-as-sequence?"] then
528528- return "[]"
529529- else
530530- return "{}"
531531- end
532532- else
533533- local oneline = nil
534534- local _2_
535535- do
536536- local tbl_0_ = {}
537537- for _, line in ipairs(lines) do
538538- tbl_0_[(#tbl_0_ + 1)] = line:gsub("^%s+", "")
539539- end
540540- _2_ = tbl_0_
541541- end
542542- oneline = table.concat(_2_, " ")
543543- if (not options["one-line?"] and (force_multi_line_3f or oneline:find("\n") or ((indent + #oneline) > options["line-length"]))) then
544544- return table.concat(lines, ("\n" .. string.rep(" ", indent)))
545545- else
546546- return oneline
547547- end
548548- end
549549- end
550550- local function pp_metamethod(t, metamethod, options, indent)
551551- if (options.level >= options.depth) then
552552- if options["empty-as-sequence?"] then
553553- return "[...]"
554554- else
555555- return "{...}"
556556- end
557557- else
558558- local _ = nil
559559- local function _2_(_241)
560560- return visible_cycle_3f(_241, options)
561561- end
562562- options["visible-cycle?"] = _2_
563563- _ = nil
564564- local lines, force_multi_line_3f = metamethod(t, pp.pp, options, indent)
565565- options["visible-cycle?"] = nil
566566- local _3_0 = type(lines)
567567- if (_3_0 == "string") then
568568- return lines
569569- elseif (_3_0 == "table") then
570570- return concat_lines(lines, options, indent, force_multi_line_3f)
571571- else
572572- local _0 = _3_0
573573- return error("Error: __fennelview metamethod must return a table of lines")
574574- end
575575- end
576576- end
577577- local function pp_table(x, options, indent)
578578- options.level = (options.level + 1)
579579- local x0 = nil
580580- do
581581- local _2_0 = nil
582582- if options["metamethod?"] then
583583- local _3_0 = x
584584- if _3_0 then
585585- local _4_0 = getmetatable(_3_0)
586586- if _4_0 then
587587- _2_0 = _4_0.__fennelview
588588- else
589589- _2_0 = _4_0
590590- end
591591- else
592592- _2_0 = _3_0
593593- end
594594- else
595595- _2_0 = nil
596596- end
597597- if (nil ~= _2_0) then
598598- local metamethod = _2_0
599599- x0 = pp_metamethod(x, metamethod, options, indent)
600600- else
601601- local _ = _2_0
602602- local _4_0, _5_0 = table_kv_pairs(x)
603603- if (true and (_5_0 == "empty")) then
604604- local _0 = _4_0
605605- if options["empty-as-sequence?"] then
606606- x0 = "[]"
607607- else
608608- x0 = "{}"
609609- end
610610- elseif ((nil ~= _4_0) and (_5_0 == "table")) then
611611- local kv = _4_0
612612- x0 = pp_associative(x, kv, options, indent)
613613- elseif ((nil ~= _4_0) and (_5_0 == "seq")) then
614614- local kv = _4_0
615615- x0 = pp_sequence(x, kv, options, indent)
616616- else
617617- x0 = nil
618618- end
619619- end
620620- end
621621- options.level = (options.level - 1)
622622- return x0
623623- end
624624- local function number__3estring(n)
625625- local _2_0, _3_0, _4_0 = math.modf(n)
626626- if ((nil ~= _2_0) and (_3_0 == 0)) then
627627- local int = _2_0
628628- return tostring(int)
629629- else
630630- local _5_
631631- do
632632- local frac = _3_0
633633- _5_ = (((_2_0 == 0) and (nil ~= _3_0)) and (frac < 0))
634634- end
635635- if _5_ then
636636- local frac = _3_0
637637- return ("-0." .. tostring(frac):gsub("^-?0.", ""))
638638- elseif ((nil ~= _2_0) and (nil ~= _3_0)) then
639639- local int = _2_0
640640- local frac = _3_0
641641- return (int .. "." .. tostring(frac):gsub("^-?0.", ""))
642642- end
643643- end
644644- end
645645- local function colon_string_3f(s)
646646- return s:find("^[-%w?\\^_!$%&*+./@:|<=>]+$")
647647- end
648648- local function make_options(t, options)
649649- local defaults = {["associative-length"] = 4, ["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["line-length"] = 80, ["metamethod?"] = true, ["one-line?"] = false, ["sequential-length"] = 10, ["utf8?"] = true, depth = 128}
650650- local overrides = {appearances = count_table_appearances(t, {}), level = 0, seen = {len = 0}}
651651- for k, v in pairs((options or {})) do
652652- defaults[k] = v
653653- end
654654- for k, v in pairs(overrides) do
655655- defaults[k] = v
656656- end
657657- return defaults
658658- end
659659- pp.pp = function(x, options, indent, key_3f)
660660- local indent0 = (indent or 0)
661661- local options0 = (options or make_options(x))
662662- local tv = type(x)
663663- local function _3_()
664664- local _2_0 = getmetatable(x)
665665- if _2_0 then
666666- return _2_0.__fennelview
667667- else
668668- return _2_0
669669- end
670670- end
671671- if ((tv == "table") or ((tv == "userdata") and _3_())) then
672672- return pp_table(x, options0, indent0)
673673- elseif (tv == "number") then
674674- return number__3estring(x)
675675- elseif ((tv == "string") and key_3f and colon_string_3f(x)) then
676676- return (":" .. x)
677677- elseif (tv == "string") then
678678- return string.format("%q", x)
679679- elseif ((tv == "boolean") or (tv == "nil")) then
680680- return tostring(x)
681681- else
682682- return ("#<" .. tostring(x) .. ">")
683683- end
684684- end
685685- local function view(x, options)
686686- return pp.pp(x, make_options(x, options), 0)
687687- end
688688- return view
692692+ return repl
689693end
690694package.preload["fennel.specials"] = package.preload["fennel.specials"] or function(...)
691695 local utils = require("fennel.utils")
···695699 local unpack = (table.unpack or _G.unpack)
696700 local SPECIALS = compiler.scopes.global.specials
697701 local function wrap_env(env)
698698- local function _0_(_, key)
699699- if (type(key) == "string") then
702702+ local function _415_(_, key)
703703+ if utils["string?"](key) then
700704 return env[compiler["global-unmangling"](key)]
701705 else
702706 return env[key]
703707 end
704708 end
705705- local function _1_(_, key, value)
706706- if (type(key) == "string") then
709709+ local function _417_(_, key, value)
710710+ if utils["string?"](key) then
707711 env[compiler["global-unmangling"](key)] = value
708712 return nil
709713 else
···711715 return nil
712716 end
713717 end
714714- local function _2_()
718718+ local function _419_()
715719 local function putenv(k, v)
716716- local _3_
717717- if (type(k) == "string") then
718718- _3_ = compiler["global-unmangling"](k)
720720+ local _420_
721721+ if utils["string?"](k) then
722722+ _420_ = compiler["global-unmangling"](k)
719723 else
720720- _3_ = k
724724+ _420_ = k
721725 end
722722- return _3_, v
726726+ return _420_, v
723727 end
724728 return next, utils.kvmap(env, putenv), nil
725729 end
726726- return setmetatable({}, {__index = _0_, __newindex = _1_, __pairs = _2_})
730730+ return setmetatable({}, {__index = _415_, __newindex = _417_, __pairs = _419_})
727731 end
728728- local function current_global_names(env)
729729- return utils.kvmap((env or _G), compiler["global-unmangling"])
732732+ local function current_global_names(_3fenv)
733733+ local mt
734734+ do
735735+ local _422_ = getmetatable(_3fenv)
736736+ if ((_G.type(_422_) == "table") and (nil ~= (_422_).__pairs)) then
737737+ local mtpairs = (_422_).__pairs
738738+ local tbl_11_auto = {}
739739+ for k, v in mtpairs(_3fenv) do
740740+ local _423_, _424_ = k, v
741741+ if ((nil ~= _423_) and (nil ~= _424_)) then
742742+ local k_12_auto = _423_
743743+ local v_13_auto = _424_
744744+ tbl_11_auto[k_12_auto] = v_13_auto
745745+ else
746746+ end
747747+ end
748748+ mt = tbl_11_auto
749749+ elseif (_422_ == nil) then
750750+ mt = (_3fenv or _G)
751751+ else
752752+ mt = nil
753753+ end
754754+ end
755755+ return (mt and utils.kvmap(mt, compiler["global-unmangling"]))
730756 end
731731- local function load_code(code, environment, filename)
732732- local environment0 = (environment or rawget(_G, "_ENV") or _G)
733733- if (rawget(_G, "setfenv") and rawget(_G, "loadstring")) then
734734- local f = assert(_G.loadstring(code, filename))
735735- _G.setfenv(f, environment0)
736736- return f
757757+ local function load_code(code, _3fenv, _3ffilename)
758758+ local env = (_3fenv or rawget(_G, "_ENV") or _G)
759759+ local _427_, _428_ = rawget(_G, "setfenv"), rawget(_G, "loadstring")
760760+ if ((nil ~= _427_) and (nil ~= _428_)) then
761761+ local setfenv = _427_
762762+ local loadstring = _428_
763763+ local f = assert(loadstring(code, _3ffilename))
764764+ local _429_ = f
765765+ setfenv(_429_, env)
766766+ return _429_
767767+ elseif true then
768768+ local _ = _427_
769769+ return assert(load(code, _3ffilename, "t", env))
737770 else
738738- return assert(load(code, filename, "t", environment0))
771771+ return nil
739772 end
740773 end
741774 local function doc_2a(tgt, name)
···746779 local mt = getmetatable(tgt)
747780 if ((type(tgt) == "function") or ((type(mt) == "table") and (type(mt.__call) == "function"))) then
748781 local arglist = table.concat(((compiler.metadata):get(tgt, "fnl/arglist") or {"#<unknown-arguments>"}), " ")
749749- local _0_
750750- if (#arglist > 0) then
751751- _0_ = " "
782782+ local _431_
783783+ if (0 < #arglist) then
784784+ _431_ = " "
752785 else
753753- _0_ = ""
786786+ _431_ = ""
754787 end
755755- return string.format("(%s%s%s)\n %s", name, _0_, arglist, docstring)
788788+ return string.format("(%s%s%s)\n %s", name, _431_, arglist, docstring)
756789 else
757790 return string.format("%s\n %s", name, docstring)
758791 end
759792 end
760793 end
761761- local function doc_special(name, arglist, docstring)
762762- compiler.metadata[SPECIALS[name]] = {["fnl/arglist"] = arglist, ["fnl/docstring"] = docstring}
794794+ local function doc_special(name, arglist, docstring, body_form_3f)
795795+ compiler.metadata[SPECIALS[name]] = {["fnl/arglist"] = arglist, ["fnl/docstring"] = docstring, ["fnl/body-form?"] = body_form_3f}
763796 return nil
764797 end
765765- local function compile_do(ast, scope, parent, start)
766766- local start0 = (start or 2)
798798+ local function compile_do(ast, scope, parent, _3fstart)
799799+ local start = (_3fstart or 2)
767800 local len = #ast
768801 local sub_scope = compiler["make-scope"](scope)
769769- for i = start0, len do
802802+ for i = start, len do
770803 compiler.compile1(ast[i], sub_scope, parent, {nval = 0})
771804 end
772805 return nil
773806 end
774774- SPECIALS["do"] = function(ast, scope, parent, opts, start, chunk, sub_scope, pre_syms)
775775- local start0 = (start or 2)
776776- local sub_scope0 = (sub_scope or compiler["make-scope"](scope))
777777- local chunk0 = (chunk or {})
807807+ SPECIALS["do"] = function(ast, scope, parent, opts, _3fstart, _3fchunk, _3fsub_scope, _3fpre_syms)
808808+ local start = (_3fstart or 2)
809809+ local sub_scope = (_3fsub_scope or compiler["make-scope"](scope))
810810+ local chunk = (_3fchunk or {})
778811 local len = #ast
779812 local retexprs = {returned = true}
780813 local function compile_body(outer_target, outer_tail, outer_retexprs)
781781- if (len < start0) then
782782- compiler.compile1(nil, sub_scope0, chunk0, {tail = outer_tail, target = outer_target})
814814+ if (len < start) then
815815+ compiler.compile1(nil, sub_scope, chunk, {tail = outer_tail, target = outer_target})
783816 else
784784- for i = start0, len do
817817+ for i = start, len do
785818 local subopts = {nval = (((i ~= len) and 0) or opts.nval), tail = (((i == len) and outer_tail) or nil), target = (((i == len) and outer_target) or nil)}
786819 local _ = utils["propagate-options"](opts, subopts)
787787- local subexprs = compiler.compile1(ast[i], sub_scope0, chunk0, subopts)
820820+ local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts)
788821 if (i ~= len) then
789822 compiler["keep-side-effects"](subexprs, parent, nil, ast[i])
823823+ else
790824 end
791825 end
792826 end
793793- compiler.emit(parent, chunk0, ast)
827827+ compiler.emit(parent, chunk, ast)
794828 compiler.emit(parent, "end", ast)
829829+ utils.hook("do", ast, sub_scope)
795830 return (outer_retexprs or retexprs)
796831 end
797832 if (opts.target or (opts.nval == 0) or opts.tail) then
···800835 elseif opts.nval then
801836 local syms = {}
802837 for i = 1, opts.nval do
803803- local s = ((pre_syms and pre_syms[i]) or compiler.gensym(scope))
804804- syms[i] = s
838838+ local s = ((_3fpre_syms and (_3fpre_syms)[i]) or compiler.gensym(scope))
839839+ do end (syms)[i] = s
805840 retexprs[i] = utils.expr(s, "sym")
806841 end
807842 local outer_target = table.concat(syms, ", ")
···810845 return compile_body(outer_target, opts.tail)
811846 else
812847 local fname = compiler.gensym(scope)
813813- local fargs = nil
848848+ local fargs
814849 if scope.vararg then
815850 fargs = "..."
816851 else
817852 fargs = ""
818853 end
819854 compiler.emit(parent, string.format("local function %s(%s)", fname, fargs), ast)
820820- utils.hook("do", ast, sub_scope0)
821855 return compile_body(nil, true, utils.expr((fname .. "(" .. fargs .. ")"), "statement"))
822856 end
823857 end
824824- doc_special("do", {"..."}, "Evaluate multiple forms; return last value.")
858858+ doc_special("do", {"..."}, "Evaluate multiple forms; return last value.", true)
825859 SPECIALS.values = function(ast, scope, parent)
826860 local len = #ast
827861 local exprs = {}
···832866 for j = 2, #subexprs do
833867 table.insert(exprs, subexprs[j])
834868 end
869869+ else
835870 end
836871 end
837872 return exprs
838873 end
839874 doc_special("values", {"..."}, "Return multiple values from a function. Must be in tail position.")
840875 local function deep_tostring(x, key_3f)
841841- local elems = {}
842842- if utils["sequence?"](x) then
843843- local _0_
876876+ if utils["list?"](x) then
877877+ local _440_
878878+ do
879879+ local tbl_14_auto = {}
880880+ local i_15_auto = #tbl_14_auto
881881+ for _, v in ipairs(x) do
882882+ local val_16_auto = deep_tostring(v)
883883+ if (nil ~= val_16_auto) then
884884+ i_15_auto = (i_15_auto + 1)
885885+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
886886+ else
887887+ end
888888+ end
889889+ _440_ = tbl_14_auto
890890+ end
891891+ return ("(" .. table.concat(_440_, " ") .. ")")
892892+ elseif utils["sequence?"](x) then
893893+ local _442_
844894 do
845845- local tbl_0_ = {}
895895+ local tbl_14_auto = {}
896896+ local i_15_auto = #tbl_14_auto
846897 for _, v in ipairs(x) do
847847- tbl_0_[(#tbl_0_ + 1)] = deep_tostring(v)
898898+ local val_16_auto = deep_tostring(v)
899899+ if (nil ~= val_16_auto) then
900900+ i_15_auto = (i_15_auto + 1)
901901+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
902902+ else
903903+ end
848904 end
849849- _0_ = tbl_0_
905905+ _442_ = tbl_14_auto
850906 end
851851- return ("[" .. table.concat(_0_, " ") .. "]")
907907+ return ("[" .. table.concat(_442_, " ") .. "]")
852908 elseif utils["table?"](x) then
853853- local _0_
909909+ local _444_
854910 do
855855- local tbl_0_ = {}
856856- for k, v in pairs(x) do
857857- tbl_0_[(#tbl_0_ + 1)] = (deep_tostring(k, true) .. " " .. deep_tostring(v))
911911+ local tbl_14_auto = {}
912912+ local i_15_auto = #tbl_14_auto
913913+ for k, v in utils.stablepairs(x) do
914914+ local val_16_auto = (deep_tostring(k, true) .. " " .. deep_tostring(v))
915915+ if (nil ~= val_16_auto) then
916916+ i_15_auto = (i_15_auto + 1)
917917+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
918918+ else
919919+ end
858920 end
859859- _0_ = tbl_0_
921921+ _444_ = tbl_14_auto
860922 end
861861- return ("{" .. table.concat(_0_, " ") .. "}")
862862- elseif (key_3f and (type(x) == "string") and x:find("^[-%w?\\^_!$%&*+./@:|<=>]+$")) then
923923+ return ("{" .. table.concat(_444_, " ") .. "}")
924924+ elseif (key_3f and utils["string?"](x) and x:find("^[-%w?\\^_!$%&*+./@:|<=>]+$")) then
863925 return (":" .. x)
864864- elseif (type(x) == "string") then
926926+ elseif utils["string?"](x) then
865927 return string.format("%q", x):gsub("\\\"", "\\\\\""):gsub("\"", "\\\"")
866928 else
867929 return tostring(x)
···869931 end
870932 local function set_fn_metadata(arg_list, docstring, parent, fn_name)
871933 if utils.root.options.useMetadata then
872872- local args = nil
873873- local function _0_(v)
874874- return ("\"%s\""):format(deep_tostring(v))
934934+ local args
935935+ local function _447_(_241)
936936+ return ("\"%s\""):format(deep_tostring(_241))
875937 end
876876- args = utils.map(arg_list, _0_)
938938+ args = utils.map(arg_list, _447_)
877939 local meta_fields = {"\"fnl/arglist\"", ("{" .. table.concat(args, ", ") .. "}")}
878940 if docstring then
879941 table.insert(meta_fields, "\"fnl/docstring\"")
880942 table.insert(meta_fields, ("\"" .. docstring:gsub("%s+$", ""):gsub("\\", "\\\\"):gsub("\n", "\\n"):gsub("\"", "\\\"") .. "\""))
943943+ else
881944 end
882945 local meta_str = ("require(\"%s\").metadata"):format((utils.root.options.moduleName or "fennel"))
883946 return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", ")))
947947+ else
948948+ return nil
884949 end
885950 end
886951 local function get_fn_name(ast, scope, fn_name, multi)
887952 if (fn_name and (fn_name[1] ~= "nil")) then
888888- local _0_
953953+ local _450_
889954 if not multi then
890890- _0_ = compiler["declare-local"](fn_name, {}, scope, ast)
955955+ _450_ = compiler["declare-local"](fn_name, {}, scope, ast)
891956 else
892892- _0_ = compiler["symbol-to-expression"](fn_name, scope)[1]
957957+ _450_ = (compiler["symbol-to-expression"](fn_name, scope))[1]
893958 end
894894- return _0_, not multi, 3
959959+ return _450_, not multi, 3
895960 else
896896- return compiler.gensym(scope), true, 2
961961+ return nil, true, 2
962962+ end
963963+ end
964964+ local function compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, local_3f, arg_name_list, f_metadata)
965965+ for i = (index + 1), #ast do
966966+ compiler.compile1(ast[i], f_scope, f_chunk, {nval = (((i ~= #ast) and 0) or nil), tail = (i == #ast)})
967967+ end
968968+ local _453_
969969+ if local_3f then
970970+ _453_ = "local function %s(%s)"
971971+ else
972972+ _453_ = "%s = function(%s)"
973973+ end
974974+ compiler.emit(parent, string.format(_453_, fn_name, table.concat(arg_name_list, ", ")), ast)
975975+ compiler.emit(parent, f_chunk, ast)
976976+ compiler.emit(parent, "end", ast)
977977+ set_fn_metadata(f_metadata["fnl/arglist"], f_metadata["fnl/docstring"], parent, fn_name)
978978+ utils.hook("fn", ast, f_scope)
979979+ return utils.expr(fn_name, "sym")
980980+ end
981981+ local function compile_anonymous_fn(ast, f_scope, f_chunk, parent, index, arg_name_list, f_metadata, scope)
982982+ local fn_name = compiler.gensym(scope)
983983+ return compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, true, arg_name_list, f_metadata)
984984+ end
985985+ local function get_function_metadata(ast, arg_list, index)
986986+ local f_metadata = {["fnl/arglist"] = arg_list}
987987+ local index_2a = (index + 1)
988988+ local expr = ast[index_2a]
989989+ if (utils["string?"](expr) and (index_2a < #ast)) then
990990+ local _456_
991991+ do
992992+ local _455_ = f_metadata
993993+ _455_["fnl/docstring"] = expr
994994+ _456_ = _455_
995995+ end
996996+ return _456_, index_2a
997997+ elseif (utils["table?"](expr) and (index_2a < #ast)) then
998998+ local _457_
999999+ do
10001000+ local tbl_11_auto = f_metadata
10011001+ for k, v in pairs(expr) do
10021002+ local _458_, _459_ = k, v
10031003+ if ((nil ~= _458_) and (nil ~= _459_)) then
10041004+ local k_12_auto = _458_
10051005+ local v_13_auto = _459_
10061006+ tbl_11_auto[k_12_auto] = v_13_auto
10071007+ else
10081008+ end
10091009+ end
10101010+ _457_ = tbl_11_auto
10111011+ end
10121012+ return _457_, index_2a
10131013+ else
10141014+ return f_metadata, index
8971015 end
8981016 end
8991017 SPECIALS.fn = function(ast, scope, parent)
900900- local f_scope = nil
10181018+ local f_scope
9011019 do
902902- local _0_0 = compiler["make-scope"](scope)
903903- _0_0["vararg"] = false
904904- f_scope = _0_0
10201020+ local _462_ = compiler["make-scope"](scope)
10211021+ do end (_462_)["vararg"] = false
10221022+ f_scope = _462_
9051023 end
9061024 local f_chunk = {}
9071025 local fn_sym = utils["sym?"](ast[2])
9081026 local multi = (fn_sym and utils["multi-sym?"](fn_sym[1]))
909909- local fn_name, local_fn_3f, index = get_fn_name(ast, scope, fn_sym, multi)
10271027+ local fn_name, local_3f, index = get_fn_name(ast, scope, fn_sym, multi)
9101028 local arg_list = compiler.assert(utils["table?"](ast[index]), "expected parameters table", ast)
9111029 compiler.assert((not multi or not multi["multi-sym-method-call"]), ("unexpected multi symbol " .. tostring(fn_name)), fn_sym)
9121030 local function get_arg_name(arg)
···9141032 compiler.assert((arg == arg_list[#arg_list]), "expected vararg as last parameter", ast)
9151033 f_scope.vararg = true
9161034 return "..."
917917- elseif (utils["sym?"](arg) and (utils.deref(arg) ~= "nil") and not utils["multi-sym?"](utils.deref(arg))) then
10351035+ elseif (utils["sym?"](arg) and (tostring(arg) ~= "nil") and not utils["multi-sym?"](tostring(arg))) then
9181036 return compiler["declare-local"](arg, {}, f_scope, ast)
9191037 elseif utils["table?"](arg) then
9201038 local raw = utils.sym(compiler.gensym(scope))
···9221040 compiler.destructure(arg, raw, ast, f_scope, f_chunk, {declaration = true, nomulti = true, symtype = "arg"})
9231041 return declared
9241042 else
925925- return compiler.assert(false, ("expected symbol for function parameter: %s"):format(tostring(arg)), ast[2])
10431043+ return compiler.assert(false, ("expected symbol for function parameter: %s"):format(tostring(arg)), ast[index])
9261044 end
9271045 end
10461046+ local arg_name_list = utils.map(arg_list, get_arg_name)
10471047+ local f_metadata, index0 = get_function_metadata(ast, arg_list, index)
10481048+ if fn_name then
10491049+ return compile_named_fn(ast, f_scope, f_chunk, parent, index0, fn_name, local_3f, arg_name_list, f_metadata)
10501050+ else
10511051+ return compile_anonymous_fn(ast, f_scope, f_chunk, parent, index0, arg_name_list, f_metadata, scope)
10521052+ end
10531053+ end
10541054+ 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)
10551055+ SPECIALS.lua = function(ast, _, parent)
10561056+ compiler.assert(((#ast == 2) or (#ast == 3)), "expected 1 or 2 arguments", ast)
10571057+ local _466_
9281058 do
929929- local arg_name_list = utils.map(arg_list, get_arg_name)
930930- local index0, docstring = nil, nil
931931- if ((type(ast[(index + 1)]) == "string") and ((index + 1) < #ast)) then
932932- index0, docstring = (index + 1), ast[(index + 1)]
10591059+ local _465_ = utils["sym?"](ast[2])
10601060+ if (nil ~= _465_) then
10611061+ _466_ = tostring(_465_)
9331062 else
934934- index0, docstring = index, nil
10631063+ _466_ = _465_
9351064 end
936936- for i = (index0 + 1), #ast do
937937- compiler.compile1(ast[i], f_scope, f_chunk, {nval = (((i ~= #ast) and 0) or nil), tail = (i == #ast)})
938938- end
939939- local _2_
940940- if local_fn_3f then
941941- _2_ = "local function %s(%s)"
10651065+ end
10661066+ if ("nil" ~= _466_) then
10671067+ table.insert(parent, {ast = ast, leaf = tostring(ast[2])})
10681068+ else
10691069+ end
10701070+ local _470_
10711071+ do
10721072+ local _469_ = utils["sym?"](ast[3])
10731073+ if (nil ~= _469_) then
10741074+ _470_ = tostring(_469_)
9421075 else
943943- _2_ = "%s = function(%s)"
10761076+ _470_ = _469_
9441077 end
945945- compiler.emit(parent, string.format(_2_, fn_name, table.concat(arg_name_list, ", ")), ast)
946946- compiler.emit(parent, f_chunk, ast)
947947- compiler.emit(parent, "end", ast)
948948- set_fn_metadata(arg_list, docstring, parent, fn_name)
9491078 end
950950- utils.hook("fn", ast, f_scope)
951951- return utils.expr(fn_name, "sym")
952952- end
953953- doc_special("fn", {"name?", "args", "docstring?", "..."}, "Function syntax. May optionally include a name and docstring.\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.")
954954- SPECIALS.lua = function(ast, _, parent)
955955- compiler.assert(((#ast == 2) or (#ast == 3)), "expected 1 or 2 arguments", ast)
956956- if (ast[2] ~= nil) then
957957- table.insert(parent, {ast = ast, leaf = tostring(ast[2])})
958958- end
959959- if (ast[3] ~= nil) then
10791079+ if ("nil" ~= _470_) then
9601080 return tostring(ast[3])
961961- end
962962- end
963963- SPECIALS.doc = function(ast, scope, parent)
964964- assert(utils.root.options.useMetadata, "can't look up doc with metadata disabled.")
965965- compiler.assert((#ast == 2), "expected one argument", ast)
966966- local target = utils.deref(ast[2])
967967- local special_or_macro = (scope.specials[target] or scope.macros[target])
968968- if special_or_macro then
969969- return ("print(%q)"):format(doc_2a(special_or_macro, target))
9701081 else
971971- local value = tostring(compiler.compile1(ast[2], scope, parent, {nval = 1})[1])
972972- return ("print(require('%s').doc(%s, '%s'))"):format((utils.root.options.moduleName or "fennel"), value, tostring(ast[2]))
10821082+ return nil
9731083 end
9741084 end
975975- doc_special("doc", {"x"}, "Print the docstring and arglist for a function, macro, or special form.")
9761085 local function dot(ast, scope, parent)
9771086 compiler.assert((1 < #ast), "expected table argument", ast)
9781087 local len = #ast
979979- local _0_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
980980- local lhs = _0_[1]
10881088+ local _let_473_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
10891089+ local lhs = _let_473_[1]
9811090 if (len == 2) then
9821091 return tostring(lhs)
9831092 else
9841093 local indices = {}
9851094 for i = 3, len do
9861095 local index = ast[i]
987987- if ((type(index) == "string") and utils["valid-lua-identifier?"](index)) then
10961096+ if (utils["string?"](index) and utils["valid-lua-identifier?"](index)) then
9881097 table.insert(indices, ("." .. index))
9891098 else
990990- local _1_ = compiler.compile1(index, scope, parent, {nval = 1})
991991- local index0 = _1_[1]
10991099+ local _let_474_ = compiler.compile1(index, scope, parent, {nval = 1})
11001100+ local index0 = _let_474_[1]
9921101 table.insert(indices, ("[" .. tostring(index0) .. "]"))
9931102 end
9941103 end
···10321141 return nil
10331142 end
10341143 doc_special("var", {"name", "val"}, "Introduce new mutable local.")
11441144+ local function kv_3f(t)
11451145+ local _478_
11461146+ do
11471147+ local tbl_14_auto = {}
11481148+ local i_15_auto = #tbl_14_auto
11491149+ for k in pairs(t) do
11501150+ local val_16_auto
11511151+ if ("number" ~= type(k)) then
11521152+ val_16_auto = k
11531153+ else
11541154+ val_16_auto = nil
11551155+ end
11561156+ if (nil ~= val_16_auto) then
11571157+ i_15_auto = (i_15_auto + 1)
11581158+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
11591159+ else
11601160+ end
11611161+ end
11621162+ _478_ = tbl_14_auto
11631163+ end
11641164+ return (_478_)[1]
11651165+ end
10351166 SPECIALS.let = function(ast, scope, parent, opts)
10361167 local bindings = ast[2]
10371168 local pre_syms = {}
10381038- compiler.assert((utils["list?"](bindings) or utils["table?"](bindings)), "expected binding table", ast)
11691169+ compiler.assert((utils["table?"](bindings) and not kv_3f(bindings)), "expected binding sequence", bindings)
10391170 compiler.assert(((#bindings % 2) == 0), "expected even number of name/value bindings", ast[2])
10401040- compiler.assert((#ast >= 3), "expected body expression", ast[1])
11711171+ compiler.assert((3 <= #ast), "expected body expression", ast[1])
10411172 for _ = 1, (opts.nval or 0) do
10421173 table.insert(pre_syms, compiler.gensym(scope))
10431174 end
···10481179 end
10491180 return SPECIALS["do"](ast, scope, parent, opts, 3, sub_chunk, sub_scope, pre_syms)
10501181 end
10511051- doc_special("let", {"[name1 val1 ... nameN valN]", "..."}, "Introduces a new scope in which a given set of local bindings are used.")
11821182+ doc_special("let", {"[name1 val1 ... nameN valN]", "..."}, "Introduces a new scope in which a given set of local bindings are used.", true)
11831183+ local function get_prev_line(parent)
11841184+ if ("table" == type(parent)) then
11851185+ return get_prev_line((parent.leaf or parent[#parent]))
11861186+ else
11871187+ return (parent or "")
11881188+ end
11891189+ end
11901190+ local function disambiguate_3f(rootstr, parent)
11911191+ local function _483_()
11921192+ local _482_ = get_prev_line(parent)
11931193+ if (nil ~= _482_) then
11941194+ local prev_line = _482_
11951195+ return prev_line:match("%)$")
11961196+ else
11971197+ return nil
11981198+ end
11991199+ end
12001200+ return (rootstr:match("^{") or _483_())
12011201+ end
10521202 SPECIALS.tset = function(ast, scope, parent)
10531053- compiler.assert((#ast > 3), "expected table, key, and value arguments", ast)
10541054- local root = compiler.compile1(ast[2], scope, parent, {nval = 1})[1]
12031203+ compiler.assert((3 < #ast), "expected table, key, and value arguments", ast)
12041204+ local root = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
10551205 local keys = {}
10561206 for i = 3, (#ast - 1) do
10571057- local _0_ = compiler.compile1(ast[i], scope, parent, {nval = 1})
10581058- local key = _0_[1]
12071207+ local _let_485_ = compiler.compile1(ast[i], scope, parent, {nval = 1})
12081208+ local key = _let_485_[1]
10591209 table.insert(keys, tostring(key))
10601210 end
10611061- local value = compiler.compile1(ast[#ast], scope, parent, {nval = 1})[1]
12111211+ local value = (compiler.compile1(ast[#ast], scope, parent, {nval = 1}))[1]
10621212 local rootstr = tostring(root)
10631063- local fmtstr = nil
10641064- if rootstr:match("^{") then
12131213+ local fmtstr
12141214+ if disambiguate_3f(rootstr, parent) then
10651215 fmtstr = "do end (%s)[%s] = %s"
10661216 else
10671217 fmtstr = "%s[%s] = %s"
10681218 end
10691069- return compiler.emit(parent, fmtstr:format(tostring(root), table.concat(keys, "]["), tostring(value)), ast)
12191219+ return compiler.emit(parent, fmtstr:format(rootstr, table.concat(keys, "]["), tostring(value)), ast)
10701220 end
10711221 doc_special("tset", {"tbl", "key1", "...", "keyN", "val"}, "Set the value of a table field. Can take additional keys to set\nnested values, but all parents must contain an existing table.")
10721222 local function calculate_target(scope, opts)
···10771227 local target_exprs = {}
10781228 for i = 1, opts.nval do
10791229 local s = compiler.gensym(scope)
10801080- accum[i] = s
12301230+ do end (accum)[i] = s
10811231 target_exprs[i] = utils.expr(s, "sym")
10821232 end
10831233 return "target", opts.tail, table.concat(accum, ", "), target_exprs
···10861236 end
10871237 end
10881238 local function if_2a(ast, scope, parent, opts)
12391239+ compiler.assert((2 < #ast), "expected condition and body", ast)
10891240 local do_scope = compiler["make-scope"](scope)
10901241 local branches = {}
10911242 local wrapper, inner_tail, inner_target, target_exprs = calculate_target(scope, opts)
···10961247 compiler["keep-side-effects"](compiler.compile1(ast[i], cscope, chunk, body_opts), chunk, nil, ast[i])
10971248 return {chunk = chunk, scope = cscope}
10981249 end
12501250+ if (1 == (#ast % 2)) then
12511251+ table.insert(ast, utils.sym("nil"))
12521252+ else
12531253+ end
10991254 for i = 2, (#ast - 1), 2 do
11001255 local condchunk = {}
11011256 local res = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1})
···11061261 branch.nested = ((i ~= 2) and (next(condchunk, nil) == nil))
11071262 table.insert(branches, branch)
11081263 end
11091109- local has_else_3f = ((#ast > 3) and ((#ast % 2) == 0))
11101110- local else_branch = (has_else_3f and compile_body(#ast))
12641264+ local else_branch = compile_body(#ast)
11111265 local s = compiler.gensym(scope)
11121266 local buffer = {}
11131267 local last_buffer = buffer
11141268 for i = 1, #branches do
11151269 local branch = branches[i]
11161116- local fstr = nil
12701270+ local fstr
11171271 if not branch.nested then
11181272 fstr = "if %s then"
11191273 else
11201274 fstr = "elseif %s then"
11211275 end
11221276 local cond = tostring(branch.cond)
11231123- local cond_line = nil
11241124- if ((cond == "true") and branch.nested and (i == #branches)) then
11251125- cond_line = "else"
11261126- else
11271127- cond_line = fstr:format(cond)
11281128- end
12771277+ local cond_line = fstr:format(cond)
11291278 if branch.nested then
11301279 compiler.emit(last_buffer, branch.condchunk, ast)
11311280 else
···11361285 compiler.emit(last_buffer, cond_line, ast)
11371286 compiler.emit(last_buffer, branch.chunk, ast)
11381287 if (i == #branches) then
11391139- if has_else_3f then
11401140- compiler.emit(last_buffer, "else", ast)
11411141- compiler.emit(last_buffer, else_branch.chunk, ast)
11421142- elseif (inner_target and (cond_line ~= "else")) then
11431143- compiler.emit(last_buffer, "else", ast)
11441144- compiler.emit(last_buffer, ("%s = nil"):format(inner_target), ast)
11451145- end
12881288+ compiler.emit(last_buffer, "else", ast)
12891289+ compiler.emit(last_buffer, else_branch.chunk, ast)
11461290 compiler.emit(last_buffer, "end", ast)
11471147- elseif not branches[(i + 1)].nested then
12911291+ elseif not (branches[(i + 1)]).nested then
11481292 local next_buffer = {}
11491293 compiler.emit(last_buffer, "else", ast)
11501294 compiler.emit(last_buffer, next_buffer, ast)
11511295 compiler.emit(last_buffer, "end", ast)
11521296 last_buffer = next_buffer
12971297+ else
11531298 end
11541299 end
11551300 if (wrapper == "iife") then
···11731318 end
11741319 SPECIALS["if"] = if_2a
11751320 doc_special("if", {"cond1", "body1", "...", "condN", "bodyN"}, "Conditional form.\nTakes any number of condition/body pairs and evaluates the first body where\nthe condition evaluates to truthy. Similar to cond in other lisps.")
13211321+ local function remove_until_condition(bindings)
13221322+ local last_item = bindings[(#bindings - 1)]
13231323+ if ((utils["sym?"](last_item) and (tostring(last_item) == "&until")) or ("until" == last_item)) then
13241324+ table.remove(bindings, (#bindings - 1))
13251325+ return table.remove(bindings)
13261326+ else
13271327+ return nil
13281328+ end
13291329+ end
13301330+ local function compile_until(condition, scope, chunk)
13311331+ if condition then
13321332+ local _let_494_ = compiler.compile1(condition, scope, chunk, {nval = 1})
13331333+ local condition_lua = _let_494_[1]
13341334+ return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(condition, "expression"))
13351335+ else
13361336+ return nil
13371337+ end
13381338+ end
11761339 SPECIALS.each = function(ast, scope, parent)
11771177- compiler.assert((#ast >= 3), "expected body expression", ast[1])
13401340+ compiler.assert((3 <= #ast), "expected body expression", ast[1])
11781341 local binding = compiler.assert(utils["table?"](ast[2]), "expected binding table", ast)
13421342+ local _ = compiler.assert((2 <= #binding), "expected binding and iterator", binding)
13431343+ local until_condition = remove_until_condition(binding)
11791344 local iter = table.remove(binding, #binding)
11801345 local destructures = {}
11811346 local new_manglings = {}
11821347 local sub_scope = compiler["make-scope"](scope)
11831348 local function destructure_binding(v)
13491349+ compiler.assert(not utils["string?"](v), ("unexpected iterator clause " .. tostring(v)), binding)
11841350 if utils["sym?"](v) then
11851351 return compiler["declare-local"](v, {}, sub_scope, ast, new_manglings)
11861352 else
11871353 local raw = utils.sym(compiler.gensym(sub_scope))
11881188- destructures[raw] = v
13541354+ do end (destructures)[raw] = v
11891355 return compiler["declare-local"](raw, {}, sub_scope, ast)
11901356 end
11911357 end
11921358 local bind_vars = utils.map(binding, destructure_binding)
11931193- local vals = compiler.compile1(iter, sub_scope, parent)
13591359+ local vals = compiler.compile1(iter, scope, parent)
11941360 local val_names = utils.map(vals, tostring)
11951361 local chunk = {}
11961362 compiler.emit(parent, ("for %s in %s do"):format(table.concat(bind_vars, ", "), table.concat(val_names, ", ")), ast)
···11981364 compiler.destructure(args, raw, ast, sub_scope, chunk, {declaration = true, nomulti = true, symtype = "each"})
11991365 end
12001366 compiler["apply-manglings"](sub_scope, new_manglings, ast)
13671367+ compile_until(until_condition, sub_scope, chunk)
12011368 compile_do(ast, sub_scope, chunk, 3)
12021369 compiler.emit(parent, chunk, ast)
12031370 return compiler.emit(parent, "end", ast)
12041371 end
12051205- doc_special("each", {"[key value (iterator)]", "..."}, "Runs the body once for each set of values provided by the given iterator.\nMost commonly used with ipairs for sequential tables or pairs for undefined\norder, but can be used with any iterator.")
13721372+ doc_special("each", {"[key value (iterator)]", "..."}, "Runs the body once for each set of values provided by the given iterator.\nMost commonly used with ipairs for sequential tables or pairs for undefined\norder, but can be used with any iterator.", true)
12061373 local function while_2a(ast, scope, parent)
12071374 local len1 = #parent
12081208- local condition = compiler.compile1(ast[2], scope, parent, {nval = 1})[1]
13751375+ local condition = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
12091376 local len2 = #parent
12101377 local sub_chunk = {}
12111378 if (len1 ~= len2) then
12121379 for i = (len1 + 1), len2 do
12131380 table.insert(sub_chunk, parent[i])
12141214- parent[i] = nil
13811381+ do end (parent)[i] = nil
12151382 end
12161383 compiler.emit(parent, "while true do", ast)
12171384 compiler.emit(sub_chunk, ("if not %s then break end"):format(condition[1]), ast)
···12231390 return compiler.emit(parent, "end", ast)
12241391 end
12251392 SPECIALS["while"] = while_2a
12261226- doc_special("while", {"condition", "..."}, "The classic while loop. Evaluates body until a condition is non-truthy.")
13931393+ doc_special("while", {"condition", "..."}, "The classic while loop. Evaluates body until a condition is non-truthy.", true)
12271394 local function for_2a(ast, scope, parent)
12281395 local ranges = compiler.assert(utils["table?"](ast[2]), "expected binding table", ast)
13961396+ local until_condition = remove_until_condition(ast[2])
12291397 local binding_sym = table.remove(ast[2], 1)
12301398 local sub_scope = compiler["make-scope"](scope)
12311399 local range_args = {}
12321400 local chunk = {}
12331401 compiler.assert(utils["sym?"](binding_sym), ("unable to bind %s %s"):format(type(binding_sym), tostring(binding_sym)), ast[2])
12341234- compiler.assert((#ast >= 3), "expected body expression", ast[1])
14021402+ compiler.assert((3 <= #ast), "expected body expression", ast[1])
14031403+ compiler.assert((#ranges <= 3), "unexpected arguments", ranges[4])
12351404 for i = 1, math.min(#ranges, 3) do
12361236- range_args[i] = tostring(compiler.compile1(ranges[i], sub_scope, parent, {nval = 1})[1])
14051405+ range_args[i] = tostring((compiler.compile1(ranges[i], scope, parent, {nval = 1}))[1])
12371406 end
12381407 compiler.emit(parent, ("for %s = %s do"):format(compiler["declare-local"](binding_sym, {}, sub_scope, ast), table.concat(range_args, ", ")), ast)
14081408+ compile_until(until_condition, sub_scope, chunk)
12391409 compile_do(ast, sub_scope, chunk, 3)
12401410 compiler.emit(parent, chunk, ast)
12411411 return compiler.emit(parent, "end", ast)
12421412 end
12431413 SPECIALS["for"] = for_2a
12441244- doc_special("for", {"[index start stop step?]", "..."}, "Numeric loop construct.\nEvaluates body once for each value between start and stop (inclusive).")
14141414+ doc_special("for", {"[index start stop step?]", "..."}, "Numeric loop construct.\nEvaluates body once for each value between start and stop (inclusive).", true)
12451415 local function native_method_call(ast, _scope, _parent, target, args)
12461246- local _0_ = ast
12471247- local _ = _0_[1]
12481248- local _0 = _0_[2]
12491249- local method_string = _0_[3]
12501250- local call_string = nil
12511251- if ((target.type == "literal") or (target.type == "expression")) then
14161416+ local _let_498_ = ast
14171417+ local _ = _let_498_[1]
14181418+ local _0 = _let_498_[2]
14191419+ local method_string = _let_498_[3]
14201420+ local call_string
14211421+ if ((target.type == "literal") or (target.type == "varg") or (target.type == "expression")) then
12521422 call_string = "(%s):%s(%s)"
12531423 else
12541424 call_string = "%s:%s(%s)"
···12561426 return utils.expr(string.format(call_string, tostring(target), method_string, table.concat(args, ", ")), "statement")
12571427 end
12581428 local function nonnative_method_call(ast, scope, parent, target, args)
12591259- local method_string = tostring(compiler.compile1(ast[3], scope, parent, {nval = 1})[1])
14291429+ local method_string = tostring((compiler.compile1(ast[3], scope, parent, {nval = 1}))[1])
12601430 local args0 = {tostring(target), unpack(args)}
12611431 return utils.expr(string.format("%s[%s](%s)", tostring(target), method_string, table.concat(args0, ", ")), "statement")
12621432 end
12631433 local function double_eval_protected_method_call(ast, scope, parent, target, args)
12641264- local method_string = tostring(compiler.compile1(ast[3], scope, parent, {nval = 1})[1])
14341434+ local method_string = tostring((compiler.compile1(ast[3], scope, parent, {nval = 1}))[1])
12651435 local call = "(function(tgt, m, ...) return tgt[m](tgt, ...) end)(%s, %s)"
12661436 table.insert(args, 1, method_string)
12671437 return utils.expr(string.format(call, tostring(target), table.concat(args, ", ")), "statement")
12681438 end
12691439 local function method_call(ast, scope, parent)
12701440 compiler.assert((2 < #ast), "expected at least 2 arguments", ast)
12711271- local _0_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
12721272- local target = _0_[1]
14411441+ local _let_500_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
14421442+ local target = _let_500_[1]
12731443 local args = {}
12741444 for i = 4, #ast do
12751275- local subexprs = nil
12761276- local _1_
14451445+ local subexprs
14461446+ local _501_
12771447 if (i ~= #ast) then
12781278- _1_ = 1
14481448+ _501_ = 1
12791449 else
12801280- _1_ = nil
14501450+ _501_ = nil
12811451 end
12821282- subexprs = compiler.compile1(ast[i], scope, parent, {nval = _1_})
14521452+ subexprs = compiler.compile1(ast[i], scope, parent, {nval = _501_})
12831453 utils.map(subexprs, tostring, args)
12841454 end
12851285- if ((type(ast[3]) == "string") and utils["valid-lua-identifier?"](ast[3])) then
14551455+ if (utils["string?"](ast[3]) and utils["valid-lua-identifier?"](ast[3])) then
12861456 return native_method_call(ast, scope, parent, target, args)
12871457 elseif (target.type == "sym") then
12881458 return nonnative_method_call(ast, scope, parent, target, args)
···12951465 SPECIALS.comment = function(ast, _, parent)
12961466 local els = {}
12971467 for i = 2, #ast do
12981298- local function _1_()
12991299- local _0_0 = tostring(ast[i]):gsub("\n", " ")
13001300- return _0_0
13011301- end
13021302- table.insert(els, _1_())
14681468+ table.insert(els, view(ast[i], {["one-line?"] = true}))
13031469 end
13041304- return compiler.emit(parent, ("-- " .. table.concat(els, " ")), ast)
14701470+ return compiler.emit(parent, ("--[[ " .. table.concat(els, " ") .. " ]]"), ast)
13051471 end
13061306- doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.")
14721472+ doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true)
13071473 local function hashfn_max_used(f_scope, i, max)
13081308- local max0 = nil
14741474+ local max0
13091475 if f_scope.symmeta[("$" .. i)].used then
13101476 max0 = i
13111477 else
···13191485 end
13201486 SPECIALS.hashfn = function(ast, scope, parent)
13211487 compiler.assert((#ast == 2), "expected one argument", ast)
13221322- local f_scope = nil
14881488+ local f_scope
13231489 do
13241324- local _0_0 = compiler["make-scope"](scope)
13251325- _0_0["vararg"] = false
13261326- _0_0["hashfn"] = true
13271327- f_scope = _0_0
14901490+ local _506_ = compiler["make-scope"](scope)
14911491+ do end (_506_)["vararg"] = false
14921492+ _506_["hashfn"] = true
14931493+ f_scope = _506_
13281494 end
13291495 local f_chunk = {}
13301496 local name = compiler.gensym(scope)
···13351501 args[i] = compiler["declare-local"](utils.sym(("$" .. i)), {}, f_scope, ast)
13361502 end
13371503 local function walker(idx, node, parent_node)
13381338- if (utils["sym?"](node) and (utils.deref(node) == "$...")) then
15041504+ if (utils["sym?"](node) and (tostring(node) == "$...")) then
13391505 parent_node[idx] = utils.varg()
13401506 f_scope.vararg = true
13411507 return nil
···13481514 local max_used = hashfn_max_used(f_scope, 1, 0)
13491515 if f_scope.vararg then
13501516 compiler.assert((max_used == 0), "$ and $... in hashfn are mutually exclusive", ast)
15171517+ else
13511518 end
13521352- local arg_str = nil
15191519+ local arg_str
13531520 if f_scope.vararg then
13541354- arg_str = utils.deref(utils.varg())
15211521+ arg_str = tostring(utils.varg())
13551522 else
13561523 arg_str = table.concat(args, ", ", 1, max_used)
13571524 end
···13611528 return utils.expr(name, "sym")
13621529 end
13631530 doc_special("hashfn", {"..."}, "Function literal shorthand; args are either $... OR $1, $2, etc.")
13641364- local function define_arithmetic_special(name, zero_arity, unary_prefix, lua_name)
15311531+ local function maybe_short_circuit_protect(ast, i, name, _510_)
15321532+ local _arg_511_ = _510_
15331533+ local mac = _arg_511_["macros"]
15341534+ local call = (utils["list?"](ast) and tostring(ast[1]))
15351535+ if ((("or" == name) or ("and" == name)) and (1 < i) and (mac[call] or ("set" == call) or ("tset" == call) or ("global" == call))) then
15361536+ return utils.list(utils.sym("do"), ast)
15371537+ else
15381538+ return ast
15391539+ end
15401540+ end
15411541+ local function arithmetic_special(name, zero_arity, unary_prefix, ast, scope, parent)
15421542+ local len = #ast
15431543+ local operands = {}
15441544+ local padded_op = (" " .. name .. " ")
15451545+ for i = 2, len do
15461546+ local subast = maybe_short_circuit_protect(ast[i], i, name, scope)
15471547+ local subexprs = compiler.compile1(subast, scope, parent)
15481548+ if (i == len) then
15491549+ utils.map(subexprs, tostring, operands)
15501550+ else
15511551+ table.insert(operands, tostring(subexprs[1]))
15521552+ end
15531553+ end
15541554+ local _514_ = #operands
15551555+ if (_514_ == 0) then
15561556+ local _516_
15571557+ do
15581558+ local _515_ = zero_arity
15591559+ compiler.assert(_515_, "Expected more than 0 arguments", ast)
15601560+ _516_ = _515_
15611561+ end
15621562+ return utils.expr(_516_, "literal")
15631563+ elseif (_514_ == 1) then
15641564+ if unary_prefix then
15651565+ return ("(" .. unary_prefix .. padded_op .. operands[1] .. ")")
15661566+ else
15671567+ return operands[1]
15681568+ end
15691569+ elseif true then
15701570+ local _ = _514_
15711571+ return ("(" .. table.concat(operands, padded_op) .. ")")
15721572+ else
15731573+ return nil
15741574+ end
15751575+ end
15761576+ local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name)
15771577+ local _522_
13651578 do
13661366- local padded_op = (" " .. (lua_name or name) .. " ")
13671367- local function _0_(ast, scope, parent)
13681368- local len = #ast
13691369- if (len == 1) then
13701370- compiler.assert((zero_arity ~= nil), "Expected more than 0 arguments", ast)
13711371- return utils.expr(zero_arity, "literal")
13721372- else
13731373- local operands = {}
13741374- for i = 2, len do
13751375- local subexprs = nil
13761376- local _1_
13771377- if (i ~= len) then
13781378- _1_ = 1
13791379- else
13801380- _1_ = nil
13811381- end
13821382- subexprs = compiler.compile1(ast[i], scope, parent, {nval = _1_})
13831383- utils.map(subexprs, tostring, operands)
13841384- end
13851385- if (#operands == 1) then
13861386- if unary_prefix then
13871387- return ("(" .. unary_prefix .. padded_op .. operands[1] .. ")")
13881388- else
13891389- return operands[1]
13901390- end
13911391- else
13921392- return ("(" .. table.concat(operands, padded_op) .. ")")
13931393- end
13941394- end
15791579+ local _519_ = (_3flua_name or name)
15801580+ local _520_ = zero_arity
15811581+ local _521_ = unary_prefix
15821582+ local function _523_(...)
15831583+ return arithmetic_special(_519_, _520_, _521_, ...)
13951584 end
13961396- SPECIALS[name] = _0_
15851585+ _522_ = _523_
13971586 end
15871587+ SPECIALS[name] = _522_
13981588 return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.")
13991589 end
14001590 define_arithmetic_special("+", "0")
···14051595 define_arithmetic_special("%")
14061596 define_arithmetic_special("/", nil, "1")
14071597 define_arithmetic_special("//", nil, "1")
14081408- define_arithmetic_special("lshift", nil, "1", "<<")
14091409- define_arithmetic_special("rshift", nil, "1", ">>")
14101410- define_arithmetic_special("band", "0", "0", "&")
14111411- define_arithmetic_special("bor", "0", "0", "|")
14121412- define_arithmetic_special("bxor", "0", "0", "~")
14131413- doc_special("lshift", {"x", "n"}, "Bitwise logical left shift of x by n bits; only works in Lua 5.3+.")
14141414- doc_special("rshift", {"x", "n"}, "Bitwise logical right shift of x by n bits; only works in Lua 5.3+.")
14151415- doc_special("band", {"x1", "x2"}, "Bitwise AND of arguments; only works in Lua 5.3+.")
14161416- doc_special("bor", {"x1", "x2"}, "Bitwise OR of arguments; only works in Lua 5.3+.")
14171417- doc_special("bxor", {"x1", "x2"}, "Bitwise XOR of arguments; only works in Lua 5.3+.")
14181418- define_arithmetic_special("or", "false")
14191419- define_arithmetic_special("and", "true")
15981598+ SPECIALS["or"] = function(ast, scope, parent)
15991599+ return arithmetic_special("or", "false", nil, ast, scope, parent)
16001600+ end
16011601+ SPECIALS["and"] = function(ast, scope, parent)
16021602+ return arithmetic_special("and", "true", nil, ast, scope, parent)
16031603+ end
14201604 doc_special("and", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.")
14211605 doc_special("or", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.")
16061606+ local function bitop_special(native_name, lib_name, zero_arity, unary_prefix, ast, scope, parent)
16071607+ if (#ast == 1) then
16081608+ return compiler.assert(zero_arity, "Expected more than 0 arguments.", ast)
16091609+ else
16101610+ local len = #ast
16111611+ local operands = {}
16121612+ local padded_native_name = (" " .. native_name .. " ")
16131613+ local prefixed_lib_name = ("bit." .. lib_name)
16141614+ for i = 2, len do
16151615+ local subexprs
16161616+ local _524_
16171617+ if (i ~= len) then
16181618+ _524_ = 1
16191619+ else
16201620+ _524_ = nil
16211621+ end
16221622+ subexprs = compiler.compile1(ast[i], scope, parent, {nval = _524_})
16231623+ utils.map(subexprs, tostring, operands)
16241624+ end
16251625+ if (#operands == 1) then
16261626+ if utils.root.options.useBitLib then
16271627+ return (prefixed_lib_name .. "(" .. unary_prefix .. ", " .. operands[1] .. ")")
16281628+ else
16291629+ return ("(" .. unary_prefix .. padded_native_name .. operands[1] .. ")")
16301630+ end
16311631+ else
16321632+ if utils.root.options.useBitLib then
16331633+ return (prefixed_lib_name .. "(" .. table.concat(operands, ", ") .. ")")
16341634+ else
16351635+ return ("(" .. table.concat(operands, padded_native_name) .. ")")
16361636+ end
16371637+ end
16381638+ end
16391639+ end
16401640+ local function define_bitop_special(name, zero_arity, unary_prefix, native)
16411641+ local _534_
16421642+ do
16431643+ local _530_ = native
16441644+ local _531_ = name
16451645+ local _532_ = zero_arity
16461646+ local _533_ = unary_prefix
16471647+ local function _535_(...)
16481648+ return bitop_special(_530_, _531_, _532_, _533_, ...)
16491649+ end
16501650+ _534_ = _535_
16511651+ end
16521652+ SPECIALS[name] = _534_
16531653+ return nil
16541654+ end
16551655+ define_bitop_special("lshift", nil, "1", "<<")
16561656+ define_bitop_special("rshift", nil, "1", ">>")
16571657+ define_bitop_special("band", "0", "0", "&")
16581658+ define_bitop_special("bor", "0", "0", "|")
16591659+ define_bitop_special("bxor", "0", "0", "~")
16601660+ doc_special("lshift", {"x", "n"}, "Bitwise logical left shift of x by n bits.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
16611661+ doc_special("rshift", {"x", "n"}, "Bitwise logical right shift of x by n bits.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
16621662+ doc_special("band", {"x1", "x2", "..."}, "Bitwise AND of any number of arguments.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
16631663+ doc_special("bor", {"x1", "x2", "..."}, "Bitwise OR of any number of arguments.\nOnly works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
16641664+ 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.")
14221665 doc_special("..", {"a", "b", "..."}, "String concatenation operator; works the same as Lua but accepts more arguments.")
14231423- local function native_comparator(op, _0_0, scope, parent)
14241424- local _1_ = _0_0
14251425- local _ = _1_[1]
14261426- local lhs_ast = _1_[2]
14271427- local rhs_ast = _1_[3]
14281428- local _2_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1})
14291429- local lhs = _2_[1]
14301430- local _3_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1})
14311431- local rhs = _3_[1]
16661666+ local function native_comparator(op, _536_, scope, parent)
16671667+ local _arg_537_ = _536_
16681668+ local _ = _arg_537_[1]
16691669+ local lhs_ast = _arg_537_[2]
16701670+ local rhs_ast = _arg_537_[3]
16711671+ local _let_538_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1})
16721672+ local lhs = _let_538_[1]
16731673+ local _let_539_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1})
16741674+ local rhs = _let_539_[1]
14321675 return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs))
14331676 end
14341677 local function double_eval_protected_comparator(op, chain_op, ast, scope, parent)
···14381681 local chain = string.format(" %s ", (chain_op or "and"))
14391682 for i = 2, #ast do
14401683 table.insert(arglist, tostring(compiler.gensym(scope)))
14411441- table.insert(vals, tostring(compiler.compile1(ast[i], scope, parent, {nval = 1})[1]))
16841684+ table.insert(vals, tostring((compiler.compile1(ast[i], scope, parent, {nval = 1}))[1]))
14421685 end
14431686 for i = 1, (#arglist - 1) do
14441687 table.insert(comparisons, string.format("(%s %s %s)", arglist[i], op, arglist[(i + 1)]))
14451688 end
14461689 return string.format("(function(%s) return %s end)(%s)", table.concat(arglist, ","), table.concat(comparisons, chain), table.concat(vals, ","))
14471690 end
14481448- local function define_comparator_special(name, lua_op, chain_op)
16911691+ local function define_comparator_special(name, _3flua_op, _3fchain_op)
14491692 do
14501450- local op = (lua_op or name)
16931693+ local op = (_3flua_op or name)
14511694 local function opfn(ast, scope, parent)
14521695 compiler.assert((2 < #ast), "expected at least two arguments", ast)
14531696 if (3 == #ast) then
14541697 return native_comparator(op, ast, scope, parent)
14551698 else
14561456- return double_eval_protected_comparator(op, chain_op, ast, scope, parent)
16991699+ return double_eval_protected_comparator(op, _3fchain_op, ast, scope, parent)
14571700 end
14581701 end
14591702 SPECIALS[name] = opfn
···14661709 define_comparator_special("<=")
14671710 define_comparator_special("=", "==")
14681711 define_comparator_special("not=", "~=", "or")
14691469- SPECIALS["~="] = SPECIALS["not="]
14701470- local function define_unary_special(op, realop)
17121712+ local function define_unary_special(op, _3frealop)
14711713 local function opfn(ast, scope, parent)
14721714 compiler.assert((#ast == 2), "expected one argument", ast)
14731715 local tail = compiler.compile1(ast[2], scope, parent, {nval = 1})
14741474- return ((realop or op) .. tostring(tail[1]))
17161716+ return ((_3frealop or op) .. tostring(tail[1]))
14751717 end
14761718 SPECIALS[op] = opfn
14771719 return nil
···14791721 define_unary_special("not", "not ")
14801722 doc_special("not", {"x"}, "Logical operator; works the same as Lua.")
14811723 define_unary_special("bnot", "~")
14821482- doc_special("bnot", {"x"}, "Bitwise negation; only works in Lua 5.3+.")
17241724+ doc_special("bnot", {"x"}, "Bitwise negation; only works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
14831725 define_unary_special("length", "#")
14841726 doc_special("length", {"x"}, "Returns the length of a table or string.")
17271727+ do end (SPECIALS)["~="] = SPECIALS["not="]
14851728 SPECIALS["#"] = SPECIALS.length
14861729 SPECIALS.quote = function(ast, scope, parent)
14871487- compiler.assert((#ast == 2), "expected one argument")
17301730+ compiler.assert((#ast == 2), "expected one argument", ast)
14881731 local runtime, this_scope = true, scope
14891732 while this_scope do
14901733 this_scope = this_scope.parent
14911734 if (this_scope == compiler.scopes.compiler) then
14921735 runtime = false
17361736+ else
14931737 end
14941738 end
14951739 return compiler["do-quote"](ast[2], scope, parent, runtime)
14961740 end
14971741 doc_special("quote", {"x"}, "Quasiquote the following form. Only works in macro/compiler scope.")
14981498- local already_warned_3f = {}
14991499- local compile_env_warning = ("WARNING: Attempting to %s %s in compile" .. " scope.\nIn future versions of Fennel this will not" .. " be allowed without the\n--no-compiler-sandbox flag" .. " or passing a :compilerEnv globals table in options.\n")
15001500- local function compiler_env_warn(_, key)
15011501- local v = _G[key]
15021502- if (v and io and io.stderr and not already_warned_3f[key]) then
15031503- already_warned_3f[key] = true
15041504- do end (io.stderr):write(compile_env_warning:format("use global", key))
17421742+ local macro_loaded = {}
17431743+ local function safe_getmetatable(tbl)
17441744+ local mt = getmetatable(tbl)
17451745+ assert((mt ~= getmetatable("")), "Illegal metatable access!")
17461746+ return mt
17471747+ end
17481748+ local safe_require = nil
17491749+ local function safe_compiler_env()
17501750+ local _543_
17511751+ do
17521752+ local _542_ = rawget(_G, "utf8")
17531753+ if (nil ~= _542_) then
17541754+ _543_ = utils.copy(_542_)
17551755+ else
17561756+ _543_ = _542_
17571757+ end
17581758+ end
17591759+ return {table = utils.copy(table), math = utils.copy(math), string = utils.copy(string), pairs = utils.stablepairs, ipairs = ipairs, select = select, tostring = tostring, tonumber = tonumber, bit = rawget(_G, "bit"), pcall = pcall, xpcall = xpcall, next = next, print = print, type = type, assert = assert, error = error, setmetatable = setmetatable, getmetatable = safe_getmetatable, require = safe_require, rawlen = rawget(_G, "rawlen"), rawget = rawget, rawset = rawset, rawequal = rawequal, _VERSION = _VERSION, utf8 = _543_}
17601760+ end
17611761+ local function combined_mt_pairs(env)
17621762+ local combined = {}
17631763+ local _let_545_ = getmetatable(env)
17641764+ local __index = _let_545_["__index"]
17651765+ if ("table" == type(__index)) then
17661766+ for k, v in pairs(__index) do
17671767+ combined[k] = v
17681768+ end
17691769+ else
17701770+ end
17711771+ for k, v in next, env, nil do
17721772+ combined[k] = v
15051773 end
15061506- return v
17741774+ return next, combined, nil
15071775 end
15081508- local safe_compiler_env = setmetatable({assert = assert, bit = rawget(_G, "bit"), error = error, getmetatable = getmetatable, ipairs = ipairs, math = math, next = next, pairs = pairs, pcall = pcall, print = print, rawequal = rawequal, rawget = rawget, rawlen = rawget(_G, "rawlen"), rawset = rawset, select = select, setmetatable = setmetatable, string = string, table = table, tonumber = tonumber, tostring = tostring, type = type, xpcall = xpcall}, {__index = compiler_env_warn})
15091509- local function make_compiler_env(ast, scope, parent)
15101510- local function _1_()
17761776+ local function make_compiler_env(ast, scope, parent, _3fopts)
17771777+ local provided
17781778+ do
17791779+ local _547_ = (_3fopts or utils.root.options)
17801780+ if ((_G.type(_547_) == "table") and ((_547_)["compiler-env"] == "strict")) then
17811781+ provided = safe_compiler_env()
17821782+ elseif ((_G.type(_547_) == "table") and (nil ~= (_547_).compilerEnv)) then
17831783+ local compilerEnv = (_547_).compilerEnv
17841784+ provided = compilerEnv
17851785+ elseif ((_G.type(_547_) == "table") and (nil ~= (_547_)["compiler-env"])) then
17861786+ local compiler_env = (_547_)["compiler-env"]
17871787+ provided = compiler_env
17881788+ elseif true then
17891789+ local _ = _547_
17901790+ provided = safe_compiler_env(false)
17911791+ else
17921792+ provided = nil
17931793+ end
17941794+ end
17951795+ local env
17961796+ local function _549_(base)
17971797+ return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base))
17981798+ end
17991799+ local function _550_()
15111800 return compiler.scopes.macro
15121801 end
15131513- local function _2_(symbol)
18021802+ local function _551_(symbol)
15141803 compiler.assert(compiler.scopes.macro, "must call from macro", ast)
15151804 return compiler.scopes.macro.manglings[tostring(symbol)]
15161805 end
15171517- local function _3_(base)
15181518- return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base))
15191519- end
15201520- local function _4_(form)
18061806+ local function _552_(form)
15211807 compiler.assert(compiler.scopes.macro, "must call from macro", ast)
15221808 return compiler.macroexpand(form, compiler.scopes.macro)
15231809 end
15241524- local _6_
15251525- do
15261526- local _5_0 = utils.root.options
15271527- if ((type(_5_0) == "table") and (nil ~= _5_0.compilerEnv)) then
15281528- local compilerEnv = _5_0.compilerEnv
15291529- _6_ = compilerEnv
15301530- elseif ((type(_5_0) == "table") and (nil ~= _5_0["compiler-env"])) then
15311531- local compiler_env = _5_0["compiler-env"]
15321532- _6_ = compiler_env
18101810+ env = {_AST = ast, _CHUNK = parent, _IS_COMPILER = true, _SCOPE = scope, _SPECIALS = compiler.scopes.global.specials, _VARARG = utils.varg(), ["macro-loaded"] = macro_loaded, unpack = unpack, ["assert-compile"] = compiler.assert, view = view, version = utils.version, metadata = compiler.metadata, ["ast-source"] = utils["ast-source"], list = utils.list, ["list?"] = utils["list?"], ["table?"] = utils["table?"], sequence = utils.sequence, ["sequence?"] = utils["sequence?"], sym = utils.sym, ["sym?"] = utils["sym?"], ["multi-sym?"] = utils["multi-sym?"], comment = utils.comment, ["comment?"] = utils["comment?"], ["varg?"] = utils["varg?"], gensym = _549_, ["get-scope"] = _550_, ["in-scope?"] = _551_, macroexpand = _552_}
18111811+ env._G = env
18121812+ return setmetatable(env, {__index = provided, __newindex = provided, __pairs = combined_mt_pairs})
18131813+ end
18141814+ local function _554_(...)
18151815+ local tbl_14_auto = {}
18161816+ local i_15_auto = #tbl_14_auto
18171817+ for c in string.gmatch((package.config or ""), "([^\n]+)") do
18181818+ local val_16_auto = c
18191819+ if (nil ~= val_16_auto) then
18201820+ i_15_auto = (i_15_auto + 1)
18211821+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
15331822 else
15341534- local _ = _5_0
15351535- _6_ = safe_compiler_env
15361823 end
15371824 end
15381538- return setmetatable({["assert-compile"] = compiler.assert, ["get-scope"] = _1_, ["in-scope?"] = _2_, ["list?"] = utils["list?"], ["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(), gensym = _3_, list = utils.list, macroexpand = _4_, sequence = utils.sequence, sym = utils.sym, unpack = unpack, view = view}, {__index = _6_})
18251825+ return tbl_14_auto
15391826 end
15401540- local cfg = string.gmatch(package.config, "([^\n]+)")
15411541- local dirsep, pathsep, pathmark = (cfg() or "/"), (cfg() or ";"), (cfg() or "?")
15421542- local pkg_config = {dirsep = dirsep, pathmark = pathmark, pathsep = pathsep}
18271827+ local _local_553_ = _554_(...)
18281828+ local dirsep = _local_553_[1]
18291829+ local pathsep = _local_553_[2]
18301830+ local pathmark = _local_553_[3]
18311831+ local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or ";"), pathsep = (pathsep or "?")}
15431832 local function escapepat(str)
15441833 return string.gsub(str, "[^%w]", "%%%1")
15451834 end
15461546- local function search_module(modulename, pathstring)
18351835+ local function search_module(modulename, _3fpathstring)
15471836 local pathsepesc = escapepat(pkg_config.pathsep)
15481837 local pattern = ("([^%s]*)%s"):format(pathsepesc, pathsepesc)
15491838 local no_dot_module = modulename:gsub("%.", pkg_config.dirsep)
15501550- local fullpath = ((pathstring or utils["fennel-module"].path) .. pkg_config.pathsep)
18391839+ local fullpath = ((_3fpathstring or utils["fennel-module"].path) .. pkg_config.pathsep)
15511840 local function try_path(path)
15521841 local filename = path:gsub(escapepat(pkg_config.pathmark), no_dot_module)
15531842 local filename2 = path:gsub(escapepat(pkg_config.pathmark), modulename)
15541554- local _1_0 = (io.open(filename) or io.open(filename2))
15551555- if (nil ~= _1_0) then
15561556- local file = _1_0
18431843+ local _556_ = (io.open(filename) or io.open(filename2))
18441844+ if (nil ~= _556_) then
18451845+ local file = _556_
15571846 file:close()
15581847 return filename
18481848+ elseif true then
18491849+ local _ = _556_
18501850+ return nil, ("no file '" .. filename .. "'")
18511851+ else
18521852+ return nil
15591853 end
15601854 end
15611561- local function find_in_path(start)
15621562- local _1_0 = fullpath:match(pattern, start)
15631563- if (nil ~= _1_0) then
15641564- local path = _1_0
15651565- return (try_path(path) or find_in_path((start + #path + 1)))
18551855+ local function find_in_path(start, _3ftried_paths)
18561856+ local _558_ = fullpath:match(pattern, start)
18571857+ if (nil ~= _558_) then
18581858+ local path = _558_
18591859+ local _559_, _560_ = try_path(path)
18601860+ if (nil ~= _559_) then
18611861+ local filename = _559_
18621862+ return filename
18631863+ elseif ((_559_ == nil) and (nil ~= _560_)) then
18641864+ local error = _560_
18651865+ local function _562_()
18661866+ local _561_ = (_3ftried_paths or {})
18671867+ table.insert(_561_, error)
18681868+ return _561_
18691869+ end
18701870+ return find_in_path((start + #path + 1), _562_())
18711871+ else
18721872+ return nil
18731873+ end
18741874+ elseif true then
18751875+ local _ = _558_
18761876+ local function _564_()
18771877+ local tried_paths = table.concat((_3ftried_paths or {}), "\n\9")
18781878+ if (_VERSION < "Lua 5.4") then
18791879+ return ("\n\9" .. tried_paths)
18801880+ else
18811881+ return tried_paths
18821882+ end
18831883+ end
18841884+ return nil, _564_()
18851885+ else
18861886+ return nil
15661887 end
15671888 end
15681889 return find_in_path(1)
15691890 end
15701570- local function make_searcher(options)
15711571- local function _1_(module_name)
18911891+ local function make_searcher(_3foptions)
18921892+ local function _567_(module_name)
15721893 local opts = utils.copy(utils.root.options)
15731573- for k, v in pairs((options or {})) do
18941894+ for k, v in pairs((_3foptions or {})) do
15741895 opts[k] = v
15751896 end
15761897 opts["module-name"] = module_name
15771577- local _2_0 = search_module(module_name)
15781578- if (nil ~= _2_0) then
15791579- local filename = _2_0
15801580- local function _3_(...)
15811581- return utils["fennel-module"].dofile(filename, opts, ...)
18981898+ local _568_, _569_ = search_module(module_name)
18991899+ if (nil ~= _568_) then
19001900+ local filename = _568_
19011901+ local _572_
19021902+ do
19031903+ local _570_ = filename
19041904+ local _571_ = opts
19051905+ local function _573_(...)
19061906+ return utils["fennel-module"].dofile(_570_, _571_, ...)
19071907+ end
19081908+ _572_ = _573_
15821909 end
15831583- return _3_, filename
19101910+ return _572_, filename
19111911+ elseif ((_568_ == nil) and (nil ~= _569_)) then
19121912+ local error = _569_
19131913+ return error
19141914+ else
19151915+ return nil
15841916 end
15851917 end
15861586- return _1_
19181918+ return _567_
19191919+ end
19201920+ local function dofile_with_searcher(fennel_macro_searcher, filename, opts, ...)
19211921+ local searchers = (package.loaders or package.searchers or {})
19221922+ local _ = table.insert(searchers, 1, fennel_macro_searcher)
19231923+ local m = utils["fennel-module"].dofile(filename, opts, ...)
19241924+ table.remove(searchers, 1)
19251925+ return m
15871926 end
15881588- local function macro_globals(env, globals)
15891589- local allowed = current_global_names(env)
15901590- for _, k in pairs((globals or {})) do
15911591- table.insert(allowed, k)
19271927+ local function fennel_macro_searcher(module_name)
19281928+ local opts
19291929+ do
19301930+ local _575_ = utils.copy(utils.root.options)
19311931+ do end (_575_)["module-name"] = module_name
19321932+ _575_["env"] = "_COMPILER"
19331933+ _575_["requireAsInclude"] = false
19341934+ _575_["allowedGlobals"] = nil
19351935+ opts = _575_
15921936 end
15931593- return allowed
19371937+ local _576_ = search_module(module_name, utils["fennel-module"]["macro-path"])
19381938+ if (nil ~= _576_) then
19391939+ local filename = _576_
19401940+ local _577_
19411941+ if (opts["compiler-env"] == _G) then
19421942+ local _578_ = fennel_macro_searcher
19431943+ local _579_ = filename
19441944+ local _580_ = opts
19451945+ local function _582_(...)
19461946+ return dofile_with_searcher(_578_, _579_, _580_, ...)
19471947+ end
19481948+ _577_ = _582_
19491949+ else
19501950+ local _583_ = filename
19511951+ local _584_ = opts
19521952+ local function _586_(...)
19531953+ return utils["fennel-module"].dofile(_583_, _584_, ...)
19541954+ end
19551955+ _577_ = _586_
19561956+ end
19571957+ return _577_, filename
19581958+ else
19591959+ return nil
19601960+ end
15941961 end
15951595- local function compiler_env_domodule(modname, env, _3fast)
15961596- local filename = compiler.assert(search_module(modname), (modname .. " module not found."), _3fast)
15971597- local globals = macro_globals(env, current_global_names())
15981598- return utils["fennel-module"].dofile(filename, {allowedGlobals = globals, env = env, scope = compiler.scopes.compiler, useMetadata = utils.root.options.useMetadata}, modname, filename)
19621962+ local function lua_macro_searcher(module_name)
19631963+ local _589_ = search_module(module_name, package.path)
19641964+ if (nil ~= _589_) then
19651965+ local filename = _589_
19661966+ local code
19671967+ do
19681968+ local f = io.open(filename)
19691969+ local function close_handlers_8_auto(ok_9_auto, ...)
19701970+ f:close()
19711971+ if ok_9_auto then
19721972+ return ...
19731973+ else
19741974+ return error(..., 0)
19751975+ end
19761976+ end
19771977+ local function _591_()
19781978+ return assert(f:read("*a"))
19791979+ end
19801980+ code = close_handlers_8_auto(_G.xpcall(_591_, (package.loaded.fennel or debug).traceback))
19811981+ end
19821982+ local chunk = load_code(code, make_compiler_env(), filename)
19831983+ return chunk, filename
19841984+ else
19851985+ return nil
19861986+ end
19871987+ end
19881988+ local macro_searchers = {fennel_macro_searcher, lua_macro_searcher}
19891989+ local function search_macro_module(modname, n)
19901990+ local _593_ = macro_searchers[n]
19911991+ if (nil ~= _593_) then
19921992+ local f = _593_
19931993+ local _594_, _595_ = f(modname)
19941994+ if ((nil ~= _594_) and true) then
19951995+ local loader = _594_
19961996+ local _3ffilename = _595_
19971997+ return loader, _3ffilename
19981998+ elseif true then
19991999+ local _ = _594_
20002000+ return search_macro_module(modname, (n + 1))
20012001+ else
20022002+ return nil
20032003+ end
20042004+ else
20052005+ return nil
20062006+ end
15992007 end
16001600- local macro_loaded = {}
16011601- local function metadata_only_fennel(modname)
20082008+ local function sandbox_fennel_module(modname)
16022009 if ((modname == "fennel.macros") or (package and package.loaded and ("table" == type(package.loaded[modname])) and (package.loaded[modname].metadata == compiler.metadata))) then
16031603- return {metadata = compiler.metadata}
20102010+ return {metadata = compiler.metadata, view = view}
20112011+ else
20122012+ return nil
16042013 end
16052014 end
16061606- safe_compiler_env.require = function(modname)
16071607- local function _1_()
16081608- local mod = compiler_env_domodule(modname, safe_compiler_env)
16091609- macro_loaded[modname] = mod
16101610- return mod
20152015+ local function _599_(modname)
20162016+ local function _600_()
20172017+ local loader, filename = search_macro_module(modname, 1)
20182018+ compiler.assert(loader, (modname .. " module not found."))
20192019+ do end (macro_loaded)[modname] = loader(modname, filename)
20202020+ return macro_loaded[modname]
16112021 end
16121612- return (macro_loaded[modname] or metadata_only_fennel(modname) or _1_())
20222022+ return (macro_loaded[modname] or sandbox_fennel_module(modname) or _600_())
16132023 end
20242024+ safe_require = _599_
16142025 local function add_macros(macros_2a, ast, scope)
16152026 compiler.assert(utils["table?"](macros_2a), "expected macros to be table", ast)
16162027 for k, v in pairs(macros_2a) do
16172028 compiler.assert((type(v) == "function"), "expected each macro to be function", ast)
16181618- scope.macros[k] = v
20292029+ compiler["check-binding-valid"](utils.sym(k), scope, ast, {["macro?"] = true})
20302030+ do end (scope.macros)[k] = v
16192031 end
16202032 return nil
16212033 end
16221622- SPECIALS["require-macros"] = function(ast, scope, parent, real_ast)
16231623- compiler.assert((#ast == 2), "Expected one module name argument", (real_ast or ast))
16241624- local filename = (ast[2].filename or ast.filename)
16251625- local modname_code = compiler.compile(ast[2])
16261626- local modname = load_code(modname_code, nil, filename)(utils.root.options["module-name"], filename)
16271627- compiler.assert((type(modname) == "string"), "module name must compile to string", (real_ast or ast))
20342034+ local function resolve_module_name(_601_, _scope, _parent, opts)
20352035+ local _arg_602_ = _601_
20362036+ local filename = _arg_602_["filename"]
20372037+ local second = _arg_602_[2]
20382038+ local filename0 = (filename or (utils["table?"](second) and second.filename))
20392039+ local module_name = utils.root.options["module-name"]
20402040+ local modexpr = compiler.compile(second, opts)
20412041+ local modname_chunk = load_code(modexpr)
20422042+ return modname_chunk(module_name, filename0)
20432043+ end
20442044+ SPECIALS["require-macros"] = function(ast, scope, parent, _3freal_ast)
20452045+ compiler.assert((#ast == 2), "Expected one module name argument", (_3freal_ast or ast))
20462046+ local modname = resolve_module_name(ast, scope, parent, {})
20472047+ compiler.assert(utils["string?"](modname), "module name must compile to string", (_3freal_ast or ast))
16282048 if not macro_loaded[modname] then
16291629- local env = make_compiler_env(ast, scope, parent)
16301630- macro_loaded[modname] = compiler_env_domodule(modname, env, ast)
20492049+ local loader, filename = search_macro_module(modname, 1)
20502050+ compiler.assert(loader, (modname .. " module not found."), ast)
20512051+ do end (macro_loaded)[modname] = compiler.assert(utils["table?"](loader(modname, filename)), "expected macros to be table", (_3freal_ast or ast))
20522052+ else
20532053+ end
20542054+ if ("import-macros" == tostring(ast[1])) then
20552055+ return macro_loaded[modname]
20562056+ else
20572057+ return add_macros(macro_loaded[modname], ast, scope, parent)
16312058 end
16321632- return add_macros(macro_loaded[modname], ast, scope, parent)
16332059 end
16342060 doc_special("require-macros", {"macro-module-name"}, "Load given module and use its contents as macro definitions in current scope.\nMacro module should return a table of macro functions with string keys.\nConsider using import-macros instead as it is more flexible.")
16352061 local function emit_included_fennel(src, path, opts, sub_chunk)
···16372063 local forms = {}
16382064 if utils.root.options.requireAsInclude then
16392065 subscope.specials.require = compiler["require-include"]
20662066+ else
16402067 end
16412068 for _, val in parser.parser(parser["string-stream"](src), path) do
16422069 table.insert(forms, val)
16432070 end
16442071 for i = 1, #forms do
16451645- local subopts = nil
20722072+ local subopts
16462073 if (i == #forms) then
16472074 subopts = {tail = true}
16482075 else
···16552082 end
16562083 local function include_path(ast, opts, path, mod, fennel_3f)
16572084 utils.root.scope.includes[mod] = "fnl/loading"
16581658- local src = nil
20852085+ local src
16592086 do
16602087 local f = assert(io.open(path))
16611661- local function close_handlers_0_(ok_0_, ...)
20882088+ local function close_handlers_8_auto(ok_9_auto, ...)
16622089 f:close()
16631663- if ok_0_ then
20902090+ if ok_9_auto then
16642091 return ...
16652092 else
16662093 return error(..., 0)
16672094 end
16682095 end
16691669- local function _1_()
16701670- return f:read("*all"):gsub("[\13\n]*$", "")
20962096+ local function _608_()
20972097+ return assert(f:read("*all")):gsub("[\13\n]*$", "")
16712098 end
16721672- src = close_handlers_0_(xpcall(_1_, (package.loaded.fennel or debug).traceback))
20992099+ src = close_handlers_8_auto(_G.xpcall(_608_, (package.loaded.fennel or debug).traceback))
16732100 end
16742101 local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement")
16752102 local target = ("package.preload[%q]"):format(mod)
···16782105 compiler.emit(temp_chunk, preload_str, ast)
16792106 compiler.emit(temp_chunk, sub_chunk)
16802107 compiler.emit(temp_chunk, "end", ast)
16811681- for i, v in ipairs(temp_chunk) do
16821682- table.insert(utils.root.chunk, i, v)
21082108+ for _, v in ipairs(temp_chunk) do
21092109+ table.insert(utils.root.chunk, v)
16832110 end
16842111 if fennel_3f then
16852112 emit_included_fennel(src, path, opts, sub_chunk)
···16932120 if (utils.root.scope.includes[mod] == "fnl/loading") then
16942121 compiler.assert(fallback, "circular include detected", ast)
16952122 return fallback(modexpr)
21232123+ else
21242124+ return nil
16962125 end
16972126 end
16982127 SPECIALS.include = function(ast, scope, parent, opts)
16992128 compiler.assert((#ast == 2), "expected one argument", ast)
17001700- local modexpr = compiler.compile1(ast[2], scope, parent, {nval = 1})[1]
21292129+ local modexpr
21302130+ do
21312131+ local _611_, _612_ = pcall(resolve_module_name, ast, scope, parent, opts)
21322132+ if ((_611_ == true) and (nil ~= _612_)) then
21332133+ local modname = _612_
21342134+ modexpr = utils.expr(string.format("%q", modname), "literal")
21352135+ elseif true then
21362136+ local _ = _611_
21372137+ modexpr = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
21382138+ else
21392139+ modexpr = nil
21402140+ end
21412141+ end
17012142 if ((modexpr.type ~= "literal") or ((modexpr[1]):byte() ~= 34)) then
17022143 if opts.fallback then
17032144 return opts.fallback(modexpr)
···17062147 end
17072148 else
17082149 local mod = load_code(("return " .. modexpr[1]))()
17091709- local function _2_()
17101710- local _1_0 = search_module(mod)
17111711- if (nil ~= _1_0) then
17121712- local fennel_path = _1_0
21502150+ local oldmod = utils.root.options["module-name"]
21512151+ local _
21522152+ utils.root.options["module-name"] = mod
21532153+ _ = nil
21542154+ local res
21552155+ local function _616_()
21562156+ local _615_ = search_module(mod)
21572157+ if (nil ~= _615_) then
21582158+ local fennel_path = _615_
17132159 return include_path(ast, opts, fennel_path, mod, true)
17141714- else
17151715- local _ = _1_0
21602160+ elseif true then
21612161+ local _0 = _615_
17162162 local lua_path = search_module(mod, package.path)
17172163 if lua_path then
17182164 return include_path(ast, opts, lua_path, mod, false)
···17212167 else
17222168 return compiler.assert(false, ("module not found " .. mod), ast)
17232169 end
21702170+ else
21712171+ return nil
17242172 end
17252173 end
17261726- return (include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _2_())
21742174+ 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 _616_())
21752175+ utils.root.options["module-name"] = oldmod
21762176+ return res
17272177 end
17282178 end
17292179 doc_special("include", {"module-name-literal"}, "Like require but load the target module during compilation and embed it in the\nLua output. The module must be a string literal and resolvable at compile time.")
···17312181 local env = make_compiler_env(ast, scope, parent)
17322182 local opts = utils.copy(utils.root.options)
17332183 opts.scope = compiler["make-scope"](compiler.scopes.compiler)
17341734- opts.allowedGlobals = macro_globals(env, current_global_names())
21842184+ opts.allowedGlobals = current_global_names(env)
17352185 return load_code(compiler.compile(ast, opts), wrap_env(env))(opts["module-name"], ast.filename)
17362186 end
17372187 SPECIALS.macros = function(ast, scope, parent)
···17432193 local old_first = ast[1]
17442194 ast[1] = utils.sym("do")
17452195 local val = eval_compiler_2a(ast, scope, parent)
17461746- ast[1] = old_first
21962196+ do end (ast)[1] = old_first
17472197 return val
17482198 end
17491749- doc_special("eval-compiler", {"..."}, "Evaluate the body at compile-time. Use the macro system instead if possible.")
17501750- return {["current-global-names"] = current_global_names, ["load-code"] = load_code, ["macro-loaded"] = macro_loaded, ["make-compiler-env"] = make_compiler_env, ["make-searcher"] = make_searcher, ["search-module"] = search_module, ["wrap-env"] = wrap_env, doc = doc_2a}
21992199+ doc_special("eval-compiler", {"..."}, "Evaluate the body at compile-time. Use the macro system instead if possible.", true)
22002200+ return {doc = doc_2a, ["current-global-names"] = current_global_names, ["load-code"] = load_code, ["macro-loaded"] = macro_loaded, ["macro-searchers"] = macro_searchers, ["make-compiler-env"] = make_compiler_env, ["search-module"] = search_module, ["make-searcher"] = make_searcher, ["wrap-env"] = wrap_env}
17512201end
17522202package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or function(...)
17532203 local utils = require("fennel.utils")
···17552205 local friend = require("fennel.friend")
17562206 local unpack = (table.unpack or _G.unpack)
17572207 local scopes = {}
17581758- local function make_scope(parent)
17591759- local parent0 = (parent or scopes.global)
17601760- local _0_
17611761- if parent0 then
17621762- _0_ = ((parent0.depth or 0) + 1)
22082208+ local function make_scope(_3fparent)
22092209+ local parent = (_3fparent or scopes.global)
22102210+ local _257_
22112211+ if parent then
22122212+ _257_ = ((parent.depth or 0) + 1)
17632213 else
17641764- _0_ = 0
22142214+ _257_ = 0
17652215 end
17661766- return {autogensyms = {}, depth = _0_, hashfn = (parent0 and parent0.hashfn), includes = setmetatable({}, {__index = (parent0 and parent0.includes)}), macros = setmetatable({}, {__index = (parent0 and parent0.macros)}), manglings = setmetatable({}, {__index = (parent0 and parent0.manglings)}), parent = parent0, refedglobals = setmetatable({}, {__index = (parent0 and parent0.refedglobals)}), specials = setmetatable({}, {__index = (parent0 and parent0.specials)}), symmeta = setmetatable({}, {__index = (parent0 and parent0.symmeta)}), unmanglings = setmetatable({}, {__index = (parent0 and parent0.unmanglings)}), vararg = (parent0 and parent0.vararg)}
22162216+ return {includes = setmetatable({}, {__index = (parent and parent.includes)}), macros = setmetatable({}, {__index = (parent and parent.macros)}), manglings = setmetatable({}, {__index = (parent and parent.manglings)}), specials = setmetatable({}, {__index = (parent and parent.specials)}), symmeta = setmetatable({}, {__index = (parent and parent.symmeta)}), unmanglings = setmetatable({}, {__index = (parent and parent.unmanglings)}), gensyms = setmetatable({}, {__index = (parent and parent.gensyms)}), autogensyms = setmetatable({}, {__index = (parent and parent.autogensyms)}), vararg = (parent and parent.vararg), depth = _257_, hashfn = (parent and parent.hashfn), refedglobals = {}, parent = parent}
17672217 end
17682218 local function assert_msg(ast, msg)
17691769- local ast_tbl = nil
22192219+ local ast_tbl
17702220 if ("table" == type(ast)) then
17712221 ast_tbl = ast
17722222 else
···17752225 local m = getmetatable(ast)
17762226 local filename = ((m and m.filename) or ast_tbl.filename or "unknown")
17772227 local line = ((m and m.line) or ast_tbl.line or "?")
17781778- local target = nil
17791779- local function _1_()
17801780- if utils["sym?"](ast_tbl[1]) then
17811781- return utils.deref(ast_tbl[1])
17821782- else
17831783- return (ast_tbl[1] or "()")
17841784- end
17851785- end
17861786- target = tostring(_1_())
17871787- return string.format("Compile error in '%s' %s:%s: %s", target, filename, line, msg)
22282228+ local col = ((m and m.col) or ast_tbl.col or "?")
22292229+ local target = tostring((utils["sym?"](ast_tbl[1]) or ast_tbl[1] or "()"))
22302230+ return string.format("%s:%s:%s Compile error in '%s': %s", filename, line, col, target, msg)
17882231 end
17892232 local function assert_compile(condition, msg, ast)
17902233 if not condition then
17911791- local _0_ = (utils.root.options or {})
17921792- local source = _0_["source"]
17931793- local unfriendly = _0_["unfriendly"]
17941794- utils.root.reset()
17951795- if unfriendly then
17961796- error(assert_msg(ast, msg), 0)
22342234+ local _let_260_ = (utils.root.options or {})
22352235+ local source = _let_260_["source"]
22362236+ local unfriendly = _let_260_["unfriendly"]
22372237+ if (nil == utils.hook("assert-compile", condition, msg, ast, utils.root.reset)) then
22382238+ utils.root.reset()
22392239+ if (unfriendly or not friend or not _G.io or not _G.io.read) then
22402240+ error(assert_msg(ast, msg), 0)
22412241+ else
22422242+ friend["assert-compile"](condition, msg, ast, source)
22432243+ end
17972244 else
17981798- friend["assert-compile"](condition, msg, ast, source)
17992245 end
22462246+ else
18002247 end
18012248 return condition
18022249 end
···18042251 scopes.global.vararg = true
18052252 scopes.compiler = make_scope(scopes.global)
18062253 scopes.macro = scopes.global
18071807- local serialize_subst = {["\11"] = "\\v", ["\12"] = "\\f", ["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "n"}
22542254+ local serialize_subst = {["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "n", ["\11"] = "\\v", ["\12"] = "\\f"}
18082255 local function serialize_string(str)
18091809- local function _0_(_241)
22562256+ local function _264_(_241)
18102257 return ("\\" .. _241:byte())
18112258 end
18121812- return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _0_)
22592259+ return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _264_)
18132260 end
18142261 local function global_mangling(str)
18152262 if utils["valid-lua-identifier?"](str) then
18162263 return str
18172264 else
18181818- local function _0_(_241)
22652265+ local function _265_(_241)
18192266 return string.format("_%02x", _241:byte())
18202267 end
18211821- return ("__fnl_global__" .. str:gsub("[^%w]", _0_))
22682268+ return ("__fnl_global__" .. str:gsub("[^%w]", _265_))
18222269 end
18232270 end
18242271 local function global_unmangling(identifier)
18251825- local _0_0 = string.match(identifier, "^__fnl_global__(.*)$")
18261826- if (nil ~= _0_0) then
18271827- local rest = _0_0
18281828- local _1_0 = nil
18291829- local function _2_(_241)
22722272+ local _267_ = string.match(identifier, "^__fnl_global__(.*)$")
22732273+ if (nil ~= _267_) then
22742274+ local rest = _267_
22752275+ local _268_
22762276+ local function _269_(_241)
18302277 return string.char(tonumber(_241:sub(2), 16))
18312278 end
18321832- _1_0 = string.gsub(rest, "_[%da-f][%da-f]", _2_)
18331833- return _1_0
22792279+ _268_ = string.gsub(rest, "_[%da-f][%da-f]", _269_)
22802280+ return _268_
22812281+ elseif true then
22822282+ local _ = _267_
22832283+ return identifier
18342284 else
18351835- local _ = _0_0
18361836- return identifier
22852285+ return nil
18372286 end
18382287 end
18392288 local allowed_globals = nil
18401840- local function global_allowed(name)
22892289+ local function global_allowed_3f(name)
18412290 return (not allowed_globals or utils["member?"](name, allowed_globals))
18422291 end
18432292 local function unique_mangling(original, mangling, scope, append)
18441844- if scope.unmanglings[mangling] then
22932293+ if (scope.unmanglings[mangling] and not scope.gensyms[mangling]) then
18452294 return unique_mangling(original, (original .. append), scope, (append + 1))
18462295 else
18472296 return mangling
18482297 end
18492298 end
18501850- local function local_mangling(str, scope, ast, temp_manglings)
22992299+ local function local_mangling(str, scope, ast, _3ftemp_manglings)
18512300 assert_compile(not utils["multi-sym?"](str), ("unexpected multi symbol " .. str), ast)
18521852- local raw = nil
18531853- if (utils["lua-keywords"][str] or str:match("^%d")) then
23012301+ local raw
23022302+ if ((utils["lua-keywords"])[str] or str:match("^%d")) then
18542303 raw = ("_" .. str)
18552304 else
18562305 raw = str
18572306 end
18581858- local mangling = nil
18591859- local function _1_(_241)
23072307+ local mangling
23082308+ local function _273_(_241)
18602309 return string.format("_%02x", _241:byte())
18612310 end
18621862- mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _1_)
23112311+ mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _273_)
18632312 local unique = unique_mangling(mangling, mangling, scope, 0)
18641864- scope.unmanglings[unique] = str
23132313+ do end (scope.unmanglings)[unique] = str
18652314 do
18661866- local manglings = (temp_manglings or scope.manglings)
18671867- manglings[str] = unique
23152315+ local manglings = (_3ftemp_manglings or scope.manglings)
23162316+ do end (manglings)[str] = unique
18682317 end
18692318 return unique
18702319 end
18712320 local function apply_manglings(scope, new_manglings, ast)
18722321 for raw, mangled in pairs(new_manglings) do
18732322 assert_compile(not scope.refedglobals[mangled], ("use of global " .. raw .. " is aliased by a local"), ast)
18741874- scope.manglings[raw] = mangled
23232323+ do end (scope.manglings)[raw] = mangled
18752324 end
18762325 return nil
18772326 end
···18902339 end
18912340 return ret
18922341 end
18931893- local function gensym(scope, base)
18941894- local append, mangling = 0, ((base or "") .. "_0_")
23422342+ local function next_append()
23432343+ utils.root.scope["gensym-append"] = ((utils.root.scope["gensym-append"] or 0) + 1)
23442344+ return ("_" .. utils.root.scope["gensym-append"] .. "_")
23452345+ end
23462346+ local function gensym(scope, _3fbase, _3fsuffix)
23472347+ local mangling = ((_3fbase or "") .. next_append() .. (_3fsuffix or ""))
18952348 while scope.unmanglings[mangling] do
18961896- mangling = ((base or "") .. "_" .. append .. "_")
18971897- append = (append + 1)
23492349+ mangling = ((_3fbase or "") .. next_append() .. (_3fsuffix or ""))
18982350 end
18991899- scope.unmanglings[mangling] = (base or true)
23512351+ scope.unmanglings[mangling] = (_3fbase or true)
23522352+ do end (scope.gensyms)[mangling] = true
19002353 return mangling
19012354 end
23552355+ local function combine_auto_gensym(parts, first)
23562356+ parts[1] = first
23572357+ local last = table.remove(parts)
23582358+ local last2 = table.remove(parts)
23592359+ local last_joiner = ((parts["multi-sym-method-call"] and ":") or ".")
23602360+ table.insert(parts, (last2 .. last_joiner .. last))
23612361+ return table.concat(parts, ".")
23622362+ end
19022363 local function autogensym(base, scope)
19031903- local _0_0 = utils["multi-sym?"](base)
19041904- if (nil ~= _0_0) then
19051905- local parts = _0_0
19061906- parts[1] = autogensym(parts[1], scope)
19071907- return table.concat(parts, ((parts["multi-sym-method-call"] and ":") or "."))
19081908- else
19091909- local _ = _0_0
19101910- local function _1_()
19111911- local mangling = gensym(scope, base:sub(1, ( - 2)))
19121912- scope.autogensyms[base] = mangling
23642364+ local _276_ = utils["multi-sym?"](base)
23652365+ if (nil ~= _276_) then
23662366+ local parts = _276_
23672367+ return combine_auto_gensym(parts, autogensym(parts[1], scope))
23682368+ elseif true then
23692369+ local _ = _276_
23702370+ local function _277_()
23712371+ local mangling = gensym(scope, base:sub(1, ( - 2)), "auto")
23722372+ do end (scope.autogensyms)[base] = mangling
19132373 return mangling
19142374 end
19151915- return (scope.autogensyms[base] or _1_())
23752375+ return (scope.autogensyms[base] or _277_())
23762376+ else
23772377+ return nil
19162378 end
19172379 end
19181918- local already_warned = {}
19191919- local function check_binding_valid(symbol, scope, ast)
19201920- local name = utils.deref(symbol)
19211921- if (io and io.stderr and name:find("&") and not already_warned[symbol]) then
19221922- already_warned[symbol] = true
19231923- do end (io.stderr):write(("-- Warning: & will not be allowed in identifier names in " .. "future versions: " .. symbol.filename .. ":" .. symbol.line .. "\n"))
23802380+ local function check_binding_valid(symbol, scope, ast, _3fopts)
23812381+ local name = tostring(symbol)
23822382+ local macro_3f
23832383+ do
23842384+ local t_279_ = _3fopts
23852385+ if (nil ~= t_279_) then
23862386+ t_279_ = (t_279_)["macro?"]
23872387+ else
23882388+ end
23892389+ macro_3f = t_279_
19242390 end
19251925- assert_compile(not (scope.specials[name] or scope.macros[name]), ("local %s was overshadowed by a special form or macro"):format(name), ast)
23912391+ assert_compile(not name:find("&"), "invalid character: &")
23922392+ assert_compile(not name:find("^%."), "invalid character: .")
23932393+ assert_compile(not (scope.specials[name] or (not macro_3f and scope.macros[name])), ("local %s was overshadowed by a special form or macro"):format(name), ast)
19262394 return assert_compile(not utils["quoted?"](symbol), string.format("macro tried to bind %s without gensym", name), symbol)
19272395 end
19281928- local function declare_local(symbol, meta, scope, ast, temp_manglings)
23962396+ local function declare_local(symbol, meta, scope, ast, _3ftemp_manglings)
19292397 check_binding_valid(symbol, scope, ast)
19301930- local name = utils.deref(symbol)
23982398+ local name = tostring(symbol)
19312399 assert_compile(not utils["multi-sym?"](name), ("unexpected multi symbol " .. name), ast)
19321932- scope.symmeta[name] = meta
19331933- return local_mangling(name, scope, ast, temp_manglings)
24002400+ do end (scope.symmeta)[name] = meta
24012401+ return local_mangling(name, scope, ast, _3ftemp_manglings)
19342402 end
19352403 local function hashfn_arg_name(name, multi_sym_parts, scope)
19362404 if not scope.hashfn then
···19402408 elseif multi_sym_parts then
19412409 if (multi_sym_parts and (multi_sym_parts[1] == "$")) then
19422410 multi_sym_parts[1] = "$1"
24112411+ else
19432412 end
19442413 return table.concat(multi_sym_parts, ".")
24142414+ else
24152415+ return nil
19452416 end
19462417 end
19471947- local function symbol_to_expression(symbol, scope, reference_3f)
19481948- utils.hook("symbol-to-expression", symbol, scope, reference_3f)
24182418+ local function symbol_to_expression(symbol, scope, _3freference_3f)
24192419+ utils.hook("symbol-to-expression", symbol, scope, _3freference_3f)
19492420 local name = symbol[1]
19502421 local multi_sym_parts = utils["multi-sym?"](name)
19512422 local name0 = (hashfn_arg_name(name, multi_sym_parts, scope) or name)
19522423 local parts = (multi_sym_parts or {name0})
19531953- local etype = (((#parts > 1) and "expression") or "sym")
24242424+ local etype = (((1 < #parts) and "expression") or "sym")
19542425 local local_3f = scope.manglings[parts[1]]
19552426 if (local_3f and scope.symmeta[parts[1]]) then
19562427 scope.symmeta[parts[1]]["used"] = true
24282428+ else
19572429 end
19581958- assert_compile((not reference_3f or local_3f or global_allowed(parts[1])), ("unknown global in strict mode: " .. parts[1]), symbol)
19591959- if (allowed_globals and not local_3f) then
19601960- utils.root.scope.refedglobals[parts[1]] = true
24302430+ assert_compile(not scope.macros[parts[1]], "tried to reference a macro at runtime", symbol)
24312431+ assert_compile((not scope.specials[parts[1]] or ("require" == parts[1])), "tried to reference a special form at runtime", symbol)
24322432+ assert_compile((not _3freference_3f or local_3f or ("_ENV" == parts[1]) or global_allowed_3f(parts[1])), ("unknown identifier in strict mode: " .. tostring(parts[1])), symbol)
24332433+ if (allowed_globals and not local_3f and scope.parent) then
24342434+ scope.parent.refedglobals[parts[1]] = true
24352435+ else
19612436 end
19622437 return utils.expr(combine_parts(parts, scope), etype)
19632438 end
19641964- local function emit(chunk, out, ast)
24392439+ local function emit(chunk, out, _3fast)
19652440 if (type(out) == "table") then
19662441 return table.insert(chunk, out)
19672442 else
19681968- return table.insert(chunk, {ast = ast, leaf = out})
24432443+ return table.insert(chunk, {ast = _3fast, leaf = out})
19692444 end
19702445 end
19712446 local function peephole(chunk)
19722447 if chunk.leaf then
19732448 return chunk
19741974- elseif ((#chunk >= 3) and (chunk[(#chunk - 2)].leaf == "do") and not chunk[(#chunk - 1)].leaf and (chunk[#chunk].leaf == "end")) then
24492449+ elseif ((3 <= #chunk) and (chunk[(#chunk - 2)].leaf == "do") and not chunk[(#chunk - 1)].leaf and (chunk[#chunk].leaf == "end")) then
19752450 local kid = peephole(chunk[(#chunk - 1)])
19762451 local new_chunk = {ast = chunk.ast}
19772452 for i = 1, (#chunk - 3) do
···19852460 return utils.map(chunk, peephole)
19862461 end
19872462 end
19881988- local function flatten_chunk_correlated(main_chunk)
24632463+ local function flatten_chunk_correlated(main_chunk, options)
19892464 local function flatten(chunk, out, last_line, file)
19902465 local last_line0 = last_line
19912466 if chunk.leaf then
19922467 out[last_line0] = ((out[last_line0] or "") .. " " .. chunk.leaf)
19932468 else
19942469 for _, subchunk in ipairs(chunk) do
19951995- if (subchunk.leaf or (#subchunk > 0)) then
19961996- if (subchunk.ast and (file == subchunk.ast.file)) then
19971997- last_line0 = math.max(last_line0, (subchunk.ast.line or 0))
24702470+ if (subchunk.leaf or (0 < #subchunk)) then
24712471+ local source = utils["ast-source"](subchunk.ast)
24722472+ if (file == source.filename) then
24732473+ last_line0 = math.max(last_line0, (source.line or 0))
24742474+ else
19982475 end
19992476 last_line0 = flatten(subchunk, out, last_line0, file)
24772477+ else
20002478 end
20012479 end
20022480 end
20032481 return last_line0
20042482 end
20052483 local out = {}
20062006- local last = flatten(main_chunk, out, 1, main_chunk.file)
24842484+ local last = flatten(main_chunk, out, 1, options.filename)
20072485 for i = 1, last do
20082486 if (out[i] == nil) then
20092487 out[i] = ""
24882488+ else
20102489 end
20112490 end
20122491 return table.concat(out, "\n")
20132492 end
20142014- local function flatten_chunk(sm, chunk, tab, depth)
24932493+ local function flatten_chunk(file_sourcemap, chunk, tab, depth)
20152494 if chunk.leaf then
20162016- local code = chunk.leaf
20172017- local info = chunk.ast
20182018- if sm then
20192019- table.insert(sm, ((info and info.line) or ( - 1)))
20202020- end
20212021- return code
24952495+ local _let_291_ = utils["ast-source"](chunk.ast)
24962496+ local filename = _let_291_["filename"]
24972497+ local line = _let_291_["line"]
24982498+ table.insert(file_sourcemap, {filename, line})
24992499+ return chunk.leaf
20222500 else
20232023- local tab0 = nil
25012501+ local tab0
20242502 do
20252025- local _0_0 = tab
20262026- if (_0_0 == true) then
25032503+ local _292_ = tab
25042504+ if (_292_ == true) then
20272505 tab0 = " "
20282028- elseif (_0_0 == false) then
25062506+ elseif (_292_ == false) then
20292507 tab0 = ""
20302030- elseif (_0_0 == tab) then
25082508+ elseif (_292_ == tab) then
20312509 tab0 = tab
20322032- elseif (_0_0 == nil) then
25102510+ elseif (_292_ == nil) then
20332511 tab0 = ""
20342512 else
20352035- tab0 = nil
25132513+ tab0 = nil
20362514 end
20372515 end
20382516 local function parter(c)
20392039- if (c.leaf or (#c > 0)) then
20402040- local sub = flatten_chunk(sm, c, tab0, (depth + 1))
20412041- if (depth > 0) then
25172517+ if (c.leaf or (0 < #c)) then
25182518+ local sub = flatten_chunk(file_sourcemap, c, tab0, (depth + 1))
25192519+ if (0 < depth) then
20422520 return (tab0 .. sub:gsub("\n", ("\n" .. tab0)))
20432521 else
20442522 return sub
20452523 end
25242524+ else
25252525+ return nil
20462526 end
20472527 end
20482528 return table.concat(utils.map(chunk, parter), "\n")
20492529 end
20502530 end
20512051- local fennel_sourcemap = {}
25312531+ local sourcemap = {}
20522532 local function make_short_src(source)
20532533 local source0 = source:gsub("\n", " ")
20542534 if (#source0 <= 49) then
···20602540 local function flatten(chunk, options)
20612541 local chunk0 = peephole(chunk)
20622542 if options.correlate then
20632063- return flatten_chunk_correlated(chunk0), {}
25432543+ return flatten_chunk_correlated(chunk0, options), {}
20642544 else
20652065- local sm = {}
20662066- local ret = flatten_chunk(sm, chunk0, options.indent, 0)
20672067- if sm then
20682068- sm.short_src = make_short_src((options.filename or options.source or ret))
20692069- if options.filename then
20702070- sm.key = ("@" .. options.filename)
20712071- else
20722072- sm.key = ret
20732073- end
20742074- fennel_sourcemap[sm.key] = sm
25452545+ local file_sourcemap = {}
25462546+ local src = flatten_chunk(file_sourcemap, chunk0, options.indent, 0)
25472547+ file_sourcemap.short_src = (options.filename or make_short_src((options.source or src)))
25482548+ if options.filename then
25492549+ file_sourcemap.key = ("@" .. options.filename)
25502550+ else
25512551+ file_sourcemap.key = src
20752552 end
20762076- return ret, sm
25532553+ sourcemap[file_sourcemap.key] = file_sourcemap
25542554+ return src, file_sourcemap
20772555 end
20782556 end
20792557 local function make_metadata()
20802080- local function _0_(self, tgt, key)
25582558+ local function _300_(self, tgt, key)
20812559 if self[tgt] then
20822560 return self[tgt][key]
25612561+ else
25622562+ return nil
20832563 end
20842564 end
20852085- local function _1_(self, tgt, key, value)
25652565+ local function _302_(self, tgt, key, value)
20862566 self[tgt] = (self[tgt] or {})
20872087- self[tgt][key] = value
25672567+ do end (self[tgt])[key] = value
20882568 return tgt
20892569 end
20902090- local function _2_(self, tgt, ...)
25702570+ local function _303_(self, tgt, ...)
20912571 local kv_len = select("#", ...)
20922572 local kvs = {...}
20932573 if ((kv_len % 2) ~= 0) then
20942574 error("metadata:setall() expected even number of k/v pairs")
25752575+ else
20952576 end
20962577 self[tgt] = (self[tgt] or {})
20972578 for i = 1, kv_len, 2 do
···20992580 end
21002581 return tgt
21012582 end
21022102- return setmetatable({}, {__index = {get = _0_, set = _1_, setall = _2_}, __mode = "k"})
25832583+ return setmetatable({}, {__index = {get = _300_, set = _302_, setall = _303_}, __mode = "k"})
21032584 end
21042585 local function exprs1(exprs)
21052105- return table.concat(utils.map(exprs, 1), ", ")
25862586+ return table.concat(utils.map(exprs, tostring), ", ")
21062587 end
21072588 local function keep_side_effects(exprs, chunk, start, ast)
21082589 local start0 = (start or 1)
···21122593 emit(chunk, string.format("do local _ = %s end", tostring(se)), ast)
21132594 elseif (se.type == "statement") then
21142595 local code = tostring(se)
21152115- emit(chunk, (((code:byte() == 40) and ("do end " .. code)) or code), ast)
25962596+ local disambiguated
25972597+ if (code:byte() == 40) then
25982598+ disambiguated = ("do end " .. code)
25992599+ else
26002600+ disambiguated = code
26012601+ end
26022602+ emit(chunk, disambiguated, ast)
26032603+ else
21162604 end
21172605 end
21182606 return nil
···21222610 local n = opts.nval
21232611 local len = #exprs
21242612 if (n ~= len) then
21252125- if (len > n) then
26132613+ if (n < len) then
21262614 keep_side_effects(exprs, parent, (n + 1), ast)
21272615 for i = (n + 1), len do
21282616 exprs[i] = nil
···21322620 exprs[i] = utils.expr("nil", "literal")
21332621 end
21342622 end
26232623+ else
21352624 end
26252625+ else
21362626 end
21372627 if opts.tail then
21382628 emit(parent, string.format("return %s", exprs1(exprs)), ast)
26292629+ else
21392630 end
21402631 if opts.target then
21412632 local result = exprs1(exprs)
21422142- local function _2_()
26332633+ local function _311_()
21432634 if (result == "") then
21442635 return "nil"
21452636 else
21462637 return result
21472638 end
21482639 end
21492149- emit(parent, string.format("%s = %s", opts.target, _2_()), ast)
26402640+ emit(parent, string.format("%s = %s", opts.target, _311_()), ast)
26412641+ else
21502642 end
21512643 if (opts.tail or opts.target) then
21522644 return {returned = true}
21532645 else
21542154- local _3_0 = exprs
21552155- _3_0["returned"] = true
21562156- return _3_0
26462646+ local _313_ = exprs
26472647+ _313_["returned"] = true
26482648+ return _313_
21572649 end
21582650 end
21592159- local function find_macro(ast, scope, multi_sym_parts)
21602160- local function find_in_table(t, i)
21612161- if (i <= #multi_sym_parts) then
21622162- return find_in_table((utils["table?"](t) and t[multi_sym_parts[i]]), (i + 1))
26512651+ local function find_macro(ast, scope)
26522652+ local macro_2a
26532653+ do
26542654+ local _315_ = utils["sym?"](ast[1])
26552655+ if (_315_ ~= nil) then
26562656+ local _316_ = tostring(_315_)
26572657+ if (_316_ ~= nil) then
26582658+ macro_2a = scope.macros[_316_]
26592659+ else
26602660+ macro_2a = _316_
26612661+ end
21632662 else
21642164- return t
26632663+ macro_2a = _315_
21652664 end
21662665 end
21672167- local macro_2a = (utils["sym?"](ast[1]) and scope.macros[utils.deref(ast[1])])
26662666+ local multi_sym_parts = utils["multi-sym?"](ast[1])
21682667 if (not macro_2a and multi_sym_parts) then
21692169- local nested_macro = find_in_table(scope.macros, 1)
26682668+ local nested_macro = utils["get-in"](scope.macros, multi_sym_parts)
21702669 assert_compile((not scope.macros[multi_sym_parts[1]] or (type(nested_macro) == "function")), "macro not found in imported macro module", ast)
21712670 return nested_macro
21722671 else
21732672 return macro_2a
21742673 end
21752674 end
21762176- local function macroexpand_2a(ast, scope, once)
21772177- if not utils["list?"](ast) then
26752675+ local function propagate_trace_info(_320_, _index, node)
26762676+ local _arg_321_ = _320_
26772677+ local filename = _arg_321_["filename"]
26782678+ local line = _arg_321_["line"]
26792679+ local bytestart = _arg_321_["bytestart"]
26802680+ local byteend = _arg_321_["byteend"]
26812681+ do
26822682+ local src = utils["ast-source"](node)
26832683+ if (("table" == type(node)) and (filename ~= src.filename)) then
26842684+ src.filename, src.line, src["from-macro?"] = filename, line, true
26852685+ src.bytestart, src.byteend = bytestart, byteend
26862686+ else
26872687+ end
26882688+ end
26892689+ return ("table" == type(node))
26902690+ end
26912691+ local function max_n(t)
26922692+ local n = 0
26932693+ for k in pairs(t) do
26942694+ if ("number" == type(k)) then
26952695+ n = math.max(k, n)
26962696+ else
26972697+ end
26982698+ end
26992699+ return n
27002700+ end
27012701+ local function quote_literal_nils(index, node, parent)
27022702+ if (parent and utils["list?"](parent)) then
27032703+ for i = 1, max_n(parent) do
27042704+ local _324_ = parent[i]
27052705+ if (_324_ == nil) then
27062706+ parent[i] = utils.sym("nil")
27072707+ else
27082708+ end
27092709+ end
27102710+ else
27112711+ end
27122712+ return index, node, parent
27132713+ end
27142714+ local function comp(f, g)
27152715+ local function _327_(...)
27162716+ return f(g(...))
27172717+ end
27182718+ return _327_
27192719+ end
27202720+ local function built_in_3f(m)
27212721+ local found_3f = false
27222722+ for _, f in pairs(scopes.global.macros) do
27232723+ if found_3f then break end
27242724+ found_3f = (f == m)
27252725+ end
27262726+ return found_3f
27272727+ end
27282728+ local function macroexpand_2a(ast, scope, _3fonce)
27292729+ local _328_
27302730+ if utils["list?"](ast) then
27312731+ _328_ = find_macro(ast, scope)
27322732+ else
27332733+ _328_ = nil
27342734+ end
27352735+ if (_328_ == false) then
21782736 return ast
21792179- else
21802180- local macro_2a = find_macro(ast, scope, utils["multi-sym?"](ast[1]))
21812181- if not macro_2a then
21822182- return ast
21832183- else
21842184- local old_scope = scopes.macro
21852185- local _ = nil
21862186- scopes.macro = scope
21872187- _ = nil
21882188- local ok, transformed = pcall(macro_2a, unpack(ast, 2))
21892189- scopes.macro = old_scope
21902190- assert_compile(ok, transformed, ast)
21912191- if (once or not transformed) then
21922192- return transformed
27372737+ elseif (nil ~= _328_) then
27382738+ local macro_2a = _328_
27392739+ local old_scope = scopes.macro
27402740+ local _
27412741+ scopes.macro = scope
27422742+ _ = nil
27432743+ local ok, transformed = nil, nil
27442744+ local function _330_()
27452745+ return macro_2a(unpack(ast, 2))
27462746+ end
27472747+ local function _331_()
27482748+ if built_in_3f(macro_2a) then
27492749+ return tostring
21932750 else
21942194- return macroexpand_2a(transformed, scope)
27512751+ return debug.traceback
21952752 end
21962753 end
27542754+ ok, transformed = xpcall(_330_, _331_())
27552755+ local _333_
27562756+ do
27572757+ local _332_ = ast
27582758+ local function _334_(...)
27592759+ return propagate_trace_info(_332_, ...)
27602760+ end
27612761+ _333_ = _334_
27622762+ end
27632763+ utils["walk-tree"](transformed, comp(_333_, quote_literal_nils))
27642764+ scopes.macro = old_scope
27652765+ assert_compile(ok, transformed, ast)
27662766+ if (_3fonce or not transformed) then
27672767+ return transformed
27682768+ else
27692769+ return macroexpand_2a(transformed, scope)
27702770+ end
27712771+ elseif true then
27722772+ local _ = _328_
27732773+ return ast
27742774+ else
27752775+ return nil
21972776 end
21982777 end
21992778 local function compile_special(ast, scope, parent, opts, special)
22002779 local exprs = (special(ast, scope, parent, opts) or utils.expr("nil", "literal"))
22012201- local exprs0 = nil
22022202- if (type(exprs) == "string") then
27802780+ local exprs0
27812781+ if ("table" ~= type(exprs)) then
22032782 exprs0 = utils.expr(exprs, "expression")
22042783 else
22052784 exprs0 = exprs
22062785 end
22072207- local exprs2 = nil
27862786+ local exprs2
22082787 if utils["expr?"](exprs0) then
22092788 exprs2 = {exprs0}
22102789 else
···22202799 end
22212800 local function compile_function_call(ast, scope, parent, opts, compile1, len)
22222801 local fargs = {}
22232223- local fcallee = compile1(ast[1], scope, parent, {nval = 1})[1]
22242224- assert_compile((fcallee.type ~= "literal"), ("cannot call literal value " .. tostring(ast[1])), ast)
28022802+ local fcallee = (compile1(ast[1], scope, parent, {nval = 1}))[1]
28032803+ assert_compile((utils["sym?"](ast[1]) or utils["list?"](ast[1]) or ("string" == type(ast[1]))), ("cannot call literal value " .. tostring(ast[1])), ast)
22252804 for i = 2, len do
22262226- local subexprs = nil
22272227- local _0_
28052805+ local subexprs
28062806+ local _340_
22282807 if (i ~= len) then
22292229- _0_ = 1
28082808+ _340_ = 1
22302809 else
22312231- _0_ = nil
28102810+ _340_ = nil
22322811 end
22332233- subexprs = compile1(ast[i], scope, parent, {nval = _0_})
22342234- table.insert(fargs, (subexprs[1] or utils.expr("nil", "literal")))
28122812+ subexprs = compile1(ast[i], scope, parent, {nval = _340_})
28132813+ table.insert(fargs, subexprs[1])
22352814 if (i == len) then
22362815 for j = 2, #subexprs do
22372816 table.insert(fargs, subexprs[j])
···22402819 keep_side_effects(subexprs, parent, 2, ast[i])
22412820 end
22422821 end
22432243- local call = string.format("%s(%s)", tostring(fcallee), exprs1(fargs))
28222822+ local pat
28232823+ if ("string" == type(ast[1])) then
28242824+ pat = "(%s)(%s)"
28252825+ else
28262826+ pat = "%s(%s)"
28272827+ end
28282828+ local call = string.format(pat, tostring(fcallee), exprs1(fargs))
22442829 return handle_compile_opts({utils.expr(call, "statement")}, parent, opts, ast)
22452830 end
22462831 local function compile_call(ast, scope, parent, opts, compile1)
···22482833 local len = #ast
22492834 local first = ast[1]
22502835 local multi_sym_parts = utils["multi-sym?"](first)
22512251- local special = (utils["sym?"](first) and scope.specials[utils.deref(first)])
22522252- assert_compile((len > 0), "expected a function, macro, or special to call", ast)
28362836+ local special = (utils["sym?"](first) and scope.specials[tostring(first)])
28372837+ assert_compile((0 < len), "expected a function, macro, or special to call", ast)
22532838 if special then
22542839 return compile_special(ast, scope, parent, opts, special)
22552840 elseif (multi_sym_parts and multi_sym_parts["multi-sym-method-call"]) then
22562841 local table_with_method = table.concat({unpack(multi_sym_parts, 1, (#multi_sym_parts - 1))}, ".")
22572842 local method_to_call = multi_sym_parts[#multi_sym_parts]
22582258- local new_ast = utils.list(utils.sym(":", scope), utils.sym(table_with_method, scope), method_to_call, select(2, unpack(ast)))
28432843+ local new_ast = utils.list(utils.sym(":", ast), utils.sym(table_with_method, ast), method_to_call, select(2, unpack(ast)))
22592844 return compile1(new_ast, scope, parent, opts)
22602845 else
22612846 return compile_function_call(ast, scope, parent, opts, compile1, len)
22622847 end
22632848 end
22642849 local function compile_varg(ast, scope, parent, opts)
22652265- assert_compile(scope.vararg, "unexpected vararg", ast)
28502850+ local _345_
28512851+ if scope.hashfn then
28522852+ _345_ = "use $... in hashfn"
28532853+ else
28542854+ _345_ = "unexpected vararg"
28552855+ end
28562856+ assert_compile(scope.vararg, _345_, ast)
22662857 return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast)
22672858 end
22682859 local function compile_sym(ast, scope, parent, opts)
22692860 local multi_sym_parts = utils["multi-sym?"](ast)
22702861 assert_compile(not (multi_sym_parts and multi_sym_parts["multi-sym-method-call"]), "multisym method calls may only be in call position", ast)
22712271- local e = nil
28622862+ local e
22722863 if (ast[1] == "nil") then
22732864 e = utils.expr("nil", "literal")
22742865 else
···22772868 return handle_compile_opts({e}, parent, opts, ast)
22782869 end
22792870 local function serialize_number(n)
22802280- local _0_0, _1_0, _2_0 = math.modf(n)
22812281- if ((nil ~= _0_0) and (_1_0 == 0)) then
22822282- local int = _0_0
22832283- return tostring(int)
22842284- else
22852285- local _3_
22862286- do
22872287- local frac = _1_0
22882288- _3_ = (((_0_0 == 0) and (nil ~= _1_0)) and (frac < 0))
22892289- end
22902290- if _3_ then
22912291- local frac = _1_0
22922292- return ("-0." .. tostring(frac):gsub("^-?0.", ""))
22932293- elseif ((nil ~= _0_0) and (nil ~= _1_0)) then
22942294- local int = _0_0
22952295- local frac = _1_0
22962296- return (int .. "." .. tostring(frac):gsub("^-?0.", ""))
22972297- end
22982298- end
28712871+ local _348_ = string.gsub(tostring(n), ",", ".")
28722872+ return _348_
22992873 end
23002874 local function compile_scalar(ast, _scope, parent, opts)
23012301- local serialize = nil
28752875+ local serialize
23022876 do
23032303- local _0_0 = type(ast)
23042304- if (_0_0 == "nil") then
28772877+ local _349_ = type(ast)
28782878+ if (_349_ == "nil") then
23052879 serialize = tostring
23062306- elseif (_0_0 == "boolean") then
28802880+ elseif (_349_ == "boolean") then
23072881 serialize = tostring
23082308- elseif (_0_0 == "string") then
28822882+ elseif (_349_ == "string") then
23092883 serialize = serialize_string
23102310- elseif (_0_0 == "number") then
28842884+ elseif (_349_ == "number") then
23112885 serialize = serialize_number
23122886 else
23132313- serialize = nil
28872887+ serialize = nil
23142888 end
23152889 end
23162890 return handle_compile_opts({utils.expr(serialize(ast), "literal")}, parent, opts)
23172891 end
23182892 local function compile_table(ast, scope, parent, opts, compile1)
23192893 local buffer = {}
23202320- for i = 1, #ast do
23212321- local nval = ((i ~= #ast) and 1)
23222322- table.insert(buffer, exprs1(compile1(ast[i], scope, parent, {nval = nval})))
23232323- end
23242894 local function write_other_values(k)
23252325- if ((type(k) ~= "number") or (math.floor(k) ~= k) or (k < 1) or (k > #ast)) then
28952895+ if ((type(k) ~= "number") or (math.floor(k) ~= k) or (k < 1) or (#ast < k)) then
23262896 if ((type(k) == "string") and utils["valid-lua-identifier?"](k)) then
23272897 return {k, k}
23282898 else
23292329- local _0_ = compile1(k, scope, parent, {nval = 1})
23302330- local compiled = _0_[1]
28992899+ local _let_351_ = compile1(k, scope, parent, {nval = 1})
29002900+ local compiled = _let_351_[1]
23312901 local kstr = ("[" .. tostring(compiled) .. "]")
23322902 return {kstr, k}
23332903 end
29042904+ else
29052905+ return nil
23342906 end
23352907 end
23362908 do
23372337- local keys = nil
29092909+ local keys
23382910 do
23392339- local _0_0 = utils.kvmap(ast, write_other_values)
23402340- local function _1_(a, b)
23412341- return (a[1] < b[1])
29112911+ local tbl_14_auto = {}
29122912+ local i_15_auto = #tbl_14_auto
29132913+ for k, v in utils.stablepairs(ast) do
29142914+ local val_16_auto = write_other_values(k, v)
29152915+ if (nil ~= val_16_auto) then
29162916+ i_15_auto = (i_15_auto + 1)
29172917+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
29182918+ else
29192919+ end
23422920 end
23432343- table.sort(_0_0, _1_)
23442344- keys = _0_0
29212921+ keys = tbl_14_auto
23452922 end
23462346- local function _1_(k)
23472347- local v = tostring(compile1(ast[k[2]], scope, parent, {nval = 1})[1])
23482348- return string.format("%s = %s", k[1], v)
29232923+ local function _357_(_355_)
29242924+ local _arg_356_ = _355_
29252925+ local k1 = _arg_356_[1]
29262926+ local k2 = _arg_356_[2]
29272927+ local _let_358_ = compile1(ast[k2], scope, parent, {nval = 1})
29282928+ local v = _let_358_[1]
29292929+ return string.format("%s = %s", k1, tostring(v))
23492930 end
23502350- utils.map(keys, _1_, buffer)
29312931+ utils.map(keys, _357_, buffer)
29322932+ end
29332933+ for i = 1, #ast do
29342934+ local nval = ((i ~= #ast) and 1)
29352935+ table.insert(buffer, exprs1(compile1(ast[i], scope, parent, {nval = nval})))
23512936 end
23522937 return handle_compile_opts({utils.expr(("{" .. table.concat(buffer, ", ") .. "}"), "expression")}, parent, opts, ast)
23532938 end
23542354- local function compile1(ast, scope, parent, opts)
23552355- local opts0 = (opts or {})
29392939+ local function compile1(ast, scope, parent, _3fopts)
29402940+ local opts = (_3fopts or {})
23562941 local ast0 = macroexpand_2a(ast, scope)
23572942 if utils["list?"](ast0) then
23582358- return compile_call(ast0, scope, parent, opts0, compile1)
29432943+ return compile_call(ast0, scope, parent, opts, compile1)
23592944 elseif utils["varg?"](ast0) then
23602360- return compile_varg(ast0, scope, parent, opts0)
29452945+ return compile_varg(ast0, scope, parent, opts)
23612946 elseif utils["sym?"](ast0) then
23622362- return compile_sym(ast0, scope, parent, opts0)
29472947+ return compile_sym(ast0, scope, parent, opts)
23632948 elseif (type(ast0) == "table") then
23642364- return compile_table(ast0, scope, parent, opts0, compile1)
29492949+ return compile_table(ast0, scope, parent, opts, compile1)
23652950 elseif ((type(ast0) == "nil") or (type(ast0) == "boolean") or (type(ast0) == "number") or (type(ast0) == "string")) then
23662366- return compile_scalar(ast0, scope, parent, opts0)
29512951+ return compile_scalar(ast0, scope, parent, opts)
23672952 else
23682953 return assert_compile(false, ("could not compile value of type " .. type(ast0)), ast0)
23692954 end
23702955 end
23712956 local function destructure(to, from, ast, scope, parent, opts)
23722957 local opts0 = (opts or {})
23732373- local _0_ = opts0
23742374- local declaration = _0_["declaration"]
23752375- local forceglobal = _0_["forceglobal"]
23762376- local forceset = _0_["forceset"]
23772377- local isvar = _0_["isvar"]
23782378- local nomulti = _0_["nomulti"]
23792379- local noundef = _0_["noundef"]
23802380- local symtype = _0_["symtype"]
29582958+ local _let_360_ = opts0
29592959+ local isvar = _let_360_["isvar"]
29602960+ local declaration = _let_360_["declaration"]
29612961+ local forceglobal = _let_360_["forceglobal"]
29622962+ local forceset = _let_360_["forceset"]
29632963+ local symtype = _let_360_["symtype"]
23812964 local symtype0 = ("_" .. (symtype or "dst"))
23822382- local setter = nil
29652965+ local setter
23832966 if declaration then
23842967 setter = "local %s = %s"
23852968 else
···23882971 local new_manglings = {}
23892972 local function getname(symbol, up1)
23902973 local raw = symbol[1]
23912391- assert_compile(not (nomulti and utils["multi-sym?"](raw)), ("unexpected multi symbol " .. raw), up1)
29742974+ assert_compile(not (opts0.nomulti and utils["multi-sym?"](raw)), ("unexpected multi symbol " .. raw), up1)
23922975 if declaration then
23932976 return declare_local(symbol, nil, scope, symbol, new_manglings)
23942977 else
23952978 local parts = (utils["multi-sym?"](raw) or {raw})
23962979 local meta = scope.symmeta[parts[1]]
29802980+ assert_compile(not raw:find(":"), "cannot set method sym", symbol)
23972981 if ((#parts == 1) and not forceset) then
23982982 assert_compile(not (forceglobal and meta), string.format("global %s conflicts with local", tostring(symbol)), symbol)
23992983 assert_compile(not (meta and not meta.var), ("expected var " .. raw), symbol)
24002400- assert_compile((meta or not noundef), ("expected local " .. parts[1]), symbol)
29842984+ assert_compile((meta or not opts0.noundef), ("expected local " .. parts[1]), symbol)
29852985+ else
24012986 end
24022987 if forceglobal then
24032988 assert_compile(not scope.symmeta[scope.unmanglings[raw]], ("global " .. raw .. " conflicts with local"), symbol)
24042404- scope.manglings[raw] = global_mangling(raw)
24052405- scope.unmanglings[global_mangling(raw)] = raw
29892989+ do end (scope.manglings)[raw] = global_mangling(raw)
29902990+ do end (scope.unmanglings)[global_mangling(raw)] = raw
24062991 if allowed_globals then
24072992 table.insert(allowed_globals, raw)
29932993+ else
24082994 end
29952995+ else
24092996 end
24102997 return symbol_to_expression(symbol, scope)[1]
24112998 end
24122999 end
24133000 local function compile_top_target(lvalues)
24142414- local inits = nil
24152415- local function _2_(_241)
30013001+ local inits
30023002+ local function _366_(_241)
24163003 if scope.manglings[_241] then
24173004 return _241
24183005 else
24193006 return "nil"
24203007 end
24213008 end
24222422- inits = utils.map(lvalues, _2_)
30093009+ inits = utils.map(lvalues, _366_)
24233010 local init = table.concat(inits, ", ")
24243011 local lvalue = table.concat(lvalues, ", ")
24252425- local plen, plast = #parent, parent[#parent]
30123012+ local plast = parent[#parent]
30133013+ local plen = #parent
24263014 local ret = compile1(from, scope, parent, {target = lvalue})
24273015 if declaration then
24283016 for pi = plen, #parent do
24293017 if (parent[pi] == plast) then
24303018 plen = pi
30193019+ else
24313020 end
24323021 end
24333022 if ((#parent == (plen + 1)) and parent[#parent].leaf) then
24343023 parent[#parent]["leaf"] = ("local " .. parent[#parent].leaf)
30243024+ elseif (init == "nil") then
30253025+ table.insert(parent, (plen + 1), {ast = ast, leaf = ("local " .. lvalue)})
24353026 else
24363027 table.insert(parent, (plen + 1), {ast = ast, leaf = ("local " .. lvalue .. " = " .. init)})
24373028 end
30293029+ else
24383030 end
24393031 return ret
24403032 end
···24473039 emit(parent, setter:format(lname, exprs1(rightexprs)), left)
24483040 end
24493041 if declaration then
24502450- scope.symmeta[utils.deref(left)] = {var = isvar}
30423042+ scope.symmeta[tostring(left)] = {var = isvar}
30433043+ return nil
30443044+ else
24513045 return nil
24523046 end
24533047 end
30483048+ 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"
30493049+ local function destructure_kv_rest(s, v, left, excluded_keys, destructure1)
30503050+ local exclude_str
30513051+ local _373_
30523052+ do
30533053+ local tbl_14_auto = {}
30543054+ local i_15_auto = #tbl_14_auto
30553055+ for _, k in ipairs(excluded_keys) do
30563056+ local val_16_auto = string.format("[%s] = true", serialize_string(k))
30573057+ if (nil ~= val_16_auto) then
30583058+ i_15_auto = (i_15_auto + 1)
30593059+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
30603060+ else
30613061+ end
30623062+ end
30633063+ _373_ = tbl_14_auto
30643064+ end
30653065+ exclude_str = table.concat(_373_, ", ")
30663066+ local subexpr = utils.expr(string.format(string.gsub(("(" .. unpack_fn .. ")(%s, %s, {%s})"), "\n%s*", " "), s, tostring(v), exclude_str), "expression")
30673067+ return destructure1(v, {subexpr}, left)
30683068+ end
30693069+ local function destructure_rest(s, k, left, destructure1)
30703070+ local unpack_str = ("(" .. unpack_fn .. ")(%s, %s)")
30713071+ local formatted = string.format(string.gsub(unpack_str, "\n%s*", " "), s, k)
30723072+ local subexpr = utils.expr(formatted, "expression")
30733073+ assert_compile((utils["sequence?"](left) and (nil == left[(k + 2)])), "expected rest argument before last parameter", left)
30743074+ return destructure1(left[(k + 1)], {subexpr}, left)
30753075+ end
24543076 local function destructure_table(left, rightexprs, top_3f, destructure1)
24553077 local s = gensym(scope, symtype0)
24562456- local right = nil
30783078+ local right
24573079 do
24582458- local _2_0 = nil
30803080+ local _375_
24593081 if top_3f then
24602460- _2_0 = exprs1(compile1(from, scope, parent))
30823082+ _375_ = exprs1(compile1(from, scope, parent))
24613083 else
24622462- _2_0 = exprs1(rightexprs)
30843084+ _375_ = exprs1(rightexprs)
24633085 end
24642464- if (_2_0 == "") then
30863086+ if (_375_ == "") then
24653087 right = "nil"
24662466- elseif (nil ~= _2_0) then
24672467- local right0 = _2_0
30883088+ elseif (nil ~= _375_) then
30893089+ local right0 = _375_
24683090 right = right0
24693091 else
24702470- right = nil
30923092+ right = nil
24713093 end
24723094 end
30953095+ local excluded_keys = {}
24733096 emit(parent, string.format("local %s = %s", s, right), left)
24743097 for k, v in utils.stablepairs(left) do
24753098 if not (("number" == type(k)) and tostring(left[(k - 1)]):find("^&")) then
24762476- if (utils["sym?"](v) and (utils.deref(v) == "&")) then
24772477- local unpack_str = "{(table.unpack or unpack)(%s, %s)}"
24782478- local formatted = string.format(unpack_str, s, k)
24792479- local subexpr = utils.expr(formatted, "expression")
24802480- assert_compile((utils["sequence?"](left) and (nil == left[(k + 2)])), "expected rest argument before last parameter", left)
24812481- destructure1(left[(k + 1)], {subexpr}, left)
24822482- elseif (utils["sym?"](k) and (utils.deref(k) == "&as")) then
30993099+ if (utils["sym?"](k) and (tostring(k) == "&")) then
31003100+ destructure_kv_rest(s, v, left, excluded_keys, destructure1)
31013101+ elseif (utils["sym?"](v) and (tostring(v) == "&")) then
31023102+ destructure_rest(s, k, left, destructure1)
31033103+ elseif (utils["sym?"](k) and (tostring(k) == "&as")) then
24833104 destructure_sym(v, {utils.expr(tostring(s))}, left)
24842484- elseif (utils["sequence?"](left) and (utils.deref(v) == "&as")) then
31053105+ elseif (utils["sequence?"](left) and (tostring(v) == "&as")) then
24853106 local _, next_sym, trailing = select(k, unpack(left))
24863107 assert_compile((nil == trailing), "expected &as argument before last parameter", left)
24873108 destructure_sym(next_sym, {utils.expr(tostring(s))}, left)
24883109 else
24892489- local key = nil
31103110+ local key
24903111 if (type(k) == "string") then
24913112 key = serialize_string(k)
24923113 else
24933114 key = k
24943115 end
24953116 local subexpr = utils.expr(string.format("%s[%s]", s, key), "expression")
31173117+ if (type(k) == "string") then
31183118+ table.insert(excluded_keys, k)
31193119+ else
31203120+ end
24963121 destructure1(v, {subexpr}, left)
24973122 end
31233123+ else
24983124 end
24993125 end
25003126 return nil
···25073133 else
25083134 local symname = gensym(scope, symtype0)
25093135 table.insert(left_names, symname)
25102510- tables[i] = {name, utils.expr(symname, "sym")}
31363136+ do end (tables)[i] = {name, utils.expr(symname, "sym")}
25113137 end
25123138 end
31393139+ assert_compile(left[1], "must provide at least one value", left)
25133140 assert_compile(top_3f, "can't nest multi-value destructuring", left)
25143141 compile_top_target(left_names)
25153142 if declaration then
25163143 for _, sym in ipairs(left) do
25172517- scope.symmeta[utils.deref(sym)] = {var = isvar}
31443144+ if utils["sym?"](sym) then
31453145+ scope.symmeta[tostring(sym)] = {var = isvar}
31463146+ else
31473147+ end
25183148 end
31493149+ else
25193150 end
25203151 for _, pair in utils.stablepairs(tables) do
25213152 destructure1(pair[1], {pair[2]}, left)
···25303161 elseif utils["list?"](left) then
25313162 destructure_values(left, up1, top_3f, destructure1)
25323163 else
25332533- assert_compile(false, string.format("unable to bind %s %s", type(left), tostring(left)), (((type(up1[2]) == "table") and up1[2]) or up1))
31643164+ assert_compile(false, string.format("unable to bind %s %s", type(left), tostring(left)), (((type((up1)[2]) == "table") and (up1)[2]) or up1))
25343165 end
25353166 if top_3f then
25363167 return {returned = true}
31683168+ else
31693169+ return nil
25373170 end
25383171 end
25393172 local ret = destructure1(to, nil, ast, true)
25402540- utils.hook("destructure", from, to, scope)
31733173+ utils.hook("destructure", from, to, scope, opts0)
25413174 apply_manglings(scope, new_manglings, ast)
25423175 return ret
25433176 end
25443177 local function require_include(ast, scope, parent, opts)
25452545- opts.fallback = function(e)
31783178+ opts.fallback = function(e, no_warn)
31793179+ if (not no_warn and ("literal" == e.type)) then
31803180+ utils.warn(("include module not found, falling back to require: %s"):format(tostring(e)))
31813181+ else
31823182+ end
25463183 return utils.expr(string.format("require(%s)", tostring(e)), "statement")
25473184 end
25483185 return scopes.global.specials.include(ast, scope, parent, opts)
···25533190 local scope = (opts.scope or make_scope(scopes.global))
25543191 local vals = {}
25553192 local chunk = {}
25562556- local _0_ = utils.root
25572557- _0_["set-reset"](_0_)
31933193+ do end (function(tgt, m, ...) return tgt[m](tgt, ...) end)(utils.root, "set-reset")
25583194 allowed_globals = opts.allowedGlobals
25593195 if (opts.indent == nil) then
25603196 opts.indent = " "
31973197+ else
25613198 end
25623199 if opts.requireAsInclude then
25633200 scope.specials.require = require_include
32013201+ else
25643202 end
25653203 utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts
25663204 for _, val in parser.parser(strm, opts.filename, opts) do
···25693207 for i = 1, #vals do
25703208 local exprs = compile1(vals[i], scope, chunk, {nval = (((i < #vals) and 0) or nil), tail = (i == #vals)})
25713209 keep_side_effects(exprs, chunk, nil, vals[i])
32103210+ if (i == #vals) then
32113211+ utils.hook("chunk", vals[i], scope)
32123212+ else
32133213+ end
25723214 end
25733215 allowed_globals = old_globals
25743216 utils.root.reset()
···25823224 local old_globals = allowed_globals
25833225 local chunk = {}
25843226 local scope = (opts0.scope or make_scope(scopes.global))
25852585- local _0_ = utils.root
25862586- _0_["set-reset"](_0_)
32273227+ do end (function(tgt, m, ...) return tgt[m](tgt, ...) end)(utils.root, "set-reset")
25873228 allowed_globals = opts0.allowedGlobals
25883229 if (opts0.indent == nil) then
25893230 opts0.indent = " "
32313231+ else
25903232 end
25913233 if opts0.requireAsInclude then
25923234 scope.specials.require = require_include
32353235+ else
25933236 end
25943237 utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts0
25953238 local exprs = compile1(ast, scope, chunk, {tail = true})
25963239 keep_side_effects(exprs, chunk, nil, ast)
32403240+ utils.hook("chunk", ast, scope)
25973241 allowed_globals = old_globals
25983242 utils.root.reset()
25993243 return flatten(chunk, opts0)
···26043248 elseif (info.what == "C") then
26053249 return " [C]: in ?"
26063250 else
26072607- local remap = fennel_sourcemap[info.source]
32513251+ local remap = sourcemap[info.source]
26083252 if (remap and remap[info.currentline]) then
26092609- info["short-src"] = remap["short-src"]
26102610- info.currentline = remap[info.currentline]
32533253+ if ((remap[info.currentline][1] or "unknown") ~= "unknown") then
32543254+ info.short_src = sourcemap[("@" .. remap[info.currentline][1])].short_src
32553255+ else
32563256+ info.short_src = remap.short_src
32573257+ end
32583258+ info.currentline = (remap[info.currentline][2] or -1)
32593259+ else
26113260 end
26123261 if (info.what == "Lua") then
26132613- local function _1_()
32623262+ local function _395_()
26143263 if info.name then
26153264 return ("'" .. info.name .. "'")
26163265 else
26173266 return "?"
26183267 end
26193268 end
26202620- return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _1_())
26212621- elseif (info["short-src"] == "(tail call)") then
32693269+ return string.format(" %s:%d: in function %s", info.short_src, info.currentline, _395_())
32703270+ elseif (info.short_src == "(tail call)") then
26223271 return " (tail call)"
26233272 else
26243273 return string.format(" %s:%d: in main chunk", info.short_src, info.currentline)
26253274 end
26263275 end
26273276 end
26282628- local function traceback(msg, start)
26292629- local msg0 = (msg or "")
26302630- if ((msg0:find("^Compile error") or msg0:find("^Parse error")) and not utils["debug-on?"]("trace")) then
26312631- return msg0
32773277+ local function traceback(_3fmsg, _3fstart)
32783278+ local msg = tostring((_3fmsg or ""))
32793279+ if ((msg:find("^Compile error") or msg:find("^Parse error")) and not utils["debug-on?"]("trace")) then
32803280+ return msg
26323281 else
26333282 local lines = {}
26342634- if (msg0:find("^Compile error") or msg0:find("^Parse error")) then
26352635- table.insert(lines, msg0)
32833283+ if (msg:find(":%d+: Compile error") or msg:find(":%d+: Parse error")) then
32843284+ table.insert(lines, msg)
26363285 else
26372637- local newmsg = msg0:gsub("^[^:]*:%d+:%s+", "runtime error: ")
32863286+ local newmsg = msg:gsub("^[^:]*:%d+:%s+", "runtime error: ")
26383287 table.insert(lines, newmsg)
26393288 end
26403289 table.insert(lines, "stack traceback:")
26412641- local done_3f, level = false, (start or 2)
32903290+ local done_3f, level = false, (_3fstart or 2)
26423291 while not done_3f do
26433292 do
26442644- local _1_0 = debug.getinfo(level, "Sln")
26452645- if (_1_0 == nil) then
32933293+ local _399_ = debug.getinfo(level, "Sln")
32943294+ if (_399_ == nil) then
26463295 done_3f = true
26472647- elseif (nil ~= _1_0) then
26482648- local info = _1_0
32963296+ elseif (nil ~= _399_) then
32973297+ local info = _399_
26493298 table.insert(lines, traceback_frame(info))
32993299+ else
26503300 end
26513301 end
26523302 level = (level + 1)
···26553305 end
26563306 end
26573307 local function entry_transform(fk, fv)
26582658- local function _0_(k, v)
33083308+ local function _402_(k, v)
26593309 if (type(k) == "number") then
26603310 return k, fv(v)
26613311 else
26623312 return fk(k), fv(v)
26633313 end
26643314 end
26652665- return _0_
26662666- end
26672667- local function no()
26682668- return nil
33153315+ return _402_
26693316 end
26703317 local function mixed_concat(t, joiner)
26713318 local seen = {}
···26793326 if not seen[k] then
26803327 ret = (ret .. s .. "[" .. k .. "]" .. "=" .. v)
26813328 s = joiner
33293329+ else
26823330 end
26833331 end
26843332 return ret
···26913339 assert_compile(not runtime_3f, "quoted ... may only be used at compile time", form)
26923340 return "_VARARG"
26933341 elseif utils["sym?"](form) then
26942694- local filename = nil
33423342+ local filename
26953343 if form.filename then
26963344 filename = string.format("%q", form.filename)
26973345 else
26983346 filename = "nil"
26993347 end
27002700- local symstr = utils.deref(form)
33483348+ local symstr = tostring(form)
27013349 assert_compile(not runtime_3f, "symbols may only be used at compile time", form)
27023350 if (symstr:find("#$") or symstr:find("#[:.]")) then
27032703- return string.format("sym('%s', nil, {filename=%s, line=%s})", autogensym(symstr, scope), filename, (form.line or "nil"))
33513351+ return string.format("sym('%s', {filename=%s, line=%s})", autogensym(symstr, scope), filename, (form.line or "nil"))
27043352 else
27052705- return string.format("sym('%s', nil, {quoted=true, filename=%s, line=%s})", symstr, filename, (form.line or "nil"))
33533353+ return string.format("sym('%s', {quoted=true, filename=%s, line=%s})", symstr, filename, (form.line or "nil"))
27063354 end
27072707- elseif (utils["list?"](form) and utils["sym?"](form[1]) and (utils.deref(form[1]) == "unquote")) then
33553355+ elseif (utils["list?"](form) and utils["sym?"](form[1]) and (tostring(form[1]) == "unquote")) then
27083356 local payload = form[2]
27093357 local res = unpack(compile1(payload, scope, parent))
27103358 return res[1]
27113359 elseif utils["list?"](form) then
27122712- local mapped = utils.kvmap(form, entry_transform(no, q))
27132713- local filename = nil
33603360+ local mapped
33613361+ local function _407_()
33623362+ return nil
33633363+ end
33643364+ mapped = utils.kvmap(form, entry_transform(_407_, q))
33653365+ local filename
27143366 if form.filename then
27153367 filename = string.format("%q", form.filename)
27163368 else
···27183370 end
27193371 assert_compile(not runtime_3f, "lists may only be used at compile time", form)
27203372 return string.format(("setmetatable({filename=%s, line=%s, bytestart=%s, %s}" .. ", getmetatable(list()))"), filename, (form.line or "nil"), (form.bytestart or "nil"), mixed_concat(mapped, ", "))
33733373+ elseif utils["sequence?"](form) then
33743374+ local mapped = utils.kvmap(form, entry_transform(q, q))
33753375+ local source = getmetatable(form)
33763376+ local filename
33773377+ if source.filename then
33783378+ filename = string.format("%q", source.filename)
33793379+ else
33803380+ filename = "nil"
33813381+ end
33823382+ local _410_
33833383+ if source then
33843384+ _410_ = source.line
33853385+ else
33863386+ _410_ = "nil"
33873387+ end
33883388+ return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _410_, "(getmetatable(sequence()))['sequence']")
27213389 elseif (type(form) == "table") then
27223390 local mapped = utils.kvmap(form, entry_transform(q, q))
27233391 local source = getmetatable(form)
27242724- local filename = nil
33923392+ local filename
27253393 if source.filename then
27263394 filename = string.format("%q", source.filename)
27273395 else
27283396 filename = "nil"
27293397 end
27302730- local function _1_()
33983398+ local function _413_()
27313399 if source then
27323400 return source.line
27333401 else
27343402 return "nil"
27353403 end
27363404 end
27372737- return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _1_())
34053405+ return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _413_())
27383406 elseif (type(form) == "string") then
27393407 return serialize_string(form)
27403408 else
27413409 return tostring(form)
27423410 end
27433411 end
27442744- return {["apply-manglings"] = apply_manglings, ["compile-stream"] = compile_stream, ["compile-string"] = compile_string, ["declare-local"] = declare_local, ["do-quote"] = do_quote, ["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, macroexpand = macroexpand_2a, metadata = make_metadata(), scopes = scopes, traceback = traceback}
34123412+ return {compile = compile, compile1 = compile1, ["compile-stream"] = compile_stream, ["compile-string"] = compile_string, ["check-binding-valid"] = check_binding_valid, emit = emit, destructure = destructure, ["require-include"] = require_include, autogensym = autogensym, gensym = gensym, ["do-quote"] = do_quote, ["global-mangling"] = global_mangling, ["global-unmangling"] = global_unmangling, ["apply-manglings"] = apply_manglings, macroexpand = macroexpand_2a, ["declare-local"] = declare_local, ["make-scope"] = make_scope, ["keep-side-effects"] = keep_side_effects, ["symbol-to-expression"] = symbol_to_expression, assert = assert_compile, scopes = scopes, traceback = traceback, metadata = make_metadata(), sourcemap = sourcemap}
27453413end
27463414package.preload["fennel.friend"] = package.preload["fennel.friend"] or function(...)
27472747- local function ast_source(ast)
27482748- local m = getmetatable(ast)
27492749- return ((m and m.line and m) or (("table" == type(ast)) and ast) or {})
27502750- end
27512751- local suggestions = {["$ and $... in hashfn are mutually exclusive"] = {"modifying the hashfn so it only contains $... or $, $1, $2, $3, etc"}, ["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"}, ["could not compile value of type "] = {"debugging the macro you're calling not to return a coroutine or userdata"}, ["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 binding table"] = {"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 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 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"}, ["illegal 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"}, ["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"}, ["unable to bind (.*)"] = {"replacing the %s with an identifier"}, ["unexpected closing delimiter (.)"] = {"deleting %s", "adding matching opening delimiter earlier"}, ["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 global in strict mode: (.*)"] = {"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 (.*)"] = {"fixing a typo so %s is used", "renaming the local to _%s"}, ["use of global (.*) is aliased by a local"] = {"renaming local %s", "refer to the global using _G.%s instead of directly"}}
34153415+ local utils = require("fennel.utils")
34163416+ local utf8_ok_3f, utf8 = pcall(require, "utf8")
34173417+ local suggestions = {["unexpected multi symbol (.*)"] = {"removing periods or colons from %s"}, ["use of global (.*) is aliased by a local"] = {"renaming local %s", "refer to the global using _G.%s instead of directly"}, ["local (.*) was overshadowed by a special form or macro"] = {"renaming local %s"}, ["global (.*) conflicts with local"] = {"renaming local %s"}, ["expected var (.*)"] = {"declaring %s using var instead of let/local", "introducing a new local instead of changing the value of %s"}, ["expected macros to be table"] = {"ensuring your macro definitions return a table"}, ["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"}, ["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"}, ["unknown identifier in strict mode: (.*)"] = {"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"}, ["expected a function.* to call"] = {"removing the empty parentheses", "using square brackets if you want an empty table"}, ["cannot call literal value"] = {"checking for typos", "checking for a missing function name"}, ["unexpected vararg"] = {"putting \"...\" at the end of the fn parameters if the vararg was intended"}, ["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"}, ["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"}, ["expected parameters"] = {"adding function parameters as a list of identifiers in brackets"}, ["unable to bind (.*)"] = {"replacing the %s with an identifier"}, ["expected rest argument before last parameter"] = {"moving & to right before the final identifier when destructuring"}, ["expected vararg as last parameter"] = {"moving the \"...\" to the end of the parameter list"}, ["expected symbol for function parameter: (.*)"] = {"changing %s to an identifier instead of a literal value"}, ["could not compile value of type "] = {"debugging the macro you're calling to return a list or table"}, ["expected local"] = {"looking for a typo", "looking for a local which is used out of its scope"}, ["expected body expression"] = {"putting some code in the body of this form after the bindings"}, ["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 even number of name/value bindings"] = {"finding where the identifier or value is missing"}, ["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"}, ["unexpected closing delimiter (.)"] = {"deleting %s", "adding matching opening delimiter earlier"}, ["mismatched closing delimiter (.), expected (.)"] = {"replacing %s with %s", "deleting %s", "adding matching opening delimiter earlier"}, ["expected even number of values in table literal"] = {"removing a key", "adding a value"}, ["expected whitespace before opening delimiter"] = {"adding whitespace"}, ["invalid character: (.)"] = {"deleting or replacing %s", "avoiding reserved characters like \", \\, ', ~, ;, @, `, and comma"}, ["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"}, ["can't start multisym segment with a digit"] = {"removing the digit", "adding a non-digit before the digit"}, ["malformed multisym"] = {"ensuring each period or colon is not followed by another period or colon"}, ["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"}, ["$ and $... in hashfn are mutually exclusive"] = {"modifying the hashfn so it only contains $... or $, $1, $2, $3, etc"}, ["tried to reference a macro at runtime"] = {"renaming the macro so as not to conflict with locals"}, ["tried to reference a special form at runtime"] = {"wrapping the special in a function if you need it to be first class"}, ["missing subject"] = {"adding an item to operate on"}, ["expected even number of pattern/body pairs"] = {"checking that every pattern has a body to go with it", "adding _ before the final body"}, ["expected at least one pattern/body pair"] = {"adding a pattern and a body to execute when the pattern matches"}, ["unexpected arguments"] = {"removing an argument", "checking for typos"}, ["unexpected iterator clause"] = {"removing an argument", "checking for typos"}}
27523418 local unpack = (table.unpack or _G.unpack)
27533419 local function suggest(msg)
27543420 local suggestion = nil
···27643430 else
27653431 suggestion = sug(matches)
27663432 end
34333433+ else
27673434 end
27683435 end
27693436 return suggestion
27703437 end
27712771- local function read_line_from_file(filename, line)
27722772- local bytes = 0
27732773- local f = assert(io.open(filename))
27742774- local _ = nil
27752775- for _0 = 1, (line - 1) do
27762776- bytes = (bytes + 1 + #f:read())
34383438+ local function read_line(filename, line, _3fsource)
34393439+ if _3fsource then
34403440+ local matcher = string.gmatch((_3fsource .. "\n"), "(.-)(\13?\n)")
34413441+ for _ = 2, line do
34423442+ matcher()
34433443+ end
34443444+ return matcher()
34453445+ else
34463446+ local f = assert(io.open(filename))
34473447+ local function close_handlers_8_auto(ok_9_auto, ...)
34483448+ f:close()
34493449+ if ok_9_auto then
34503450+ return ...
34513451+ else
34523452+ return error(..., 0)
34533453+ end
34543454+ end
34553455+ local function _178_()
34563456+ for _ = 2, line do
34573457+ f:read()
34583458+ end
34593459+ return f:read()
34603460+ end
34613461+ return close_handlers_8_auto(_G.xpcall(_178_, (package.loaded.fennel or debug).traceback))
27773462 end
27782778- _ = nil
27792779- local codeline = f:read()
27802780- f:close()
27812781- return codeline, bytes
27823463 end
27832783- local function read_line_from_source(source, line)
27842784- local lines, bytes, codeline = 0, 0
27852785- for this_line, newline in string.gmatch((source .. "\n"), "(.-)(\13?\n)") do
27862786- lines = (lines + 1)
27872787- if (lines == line) then
27882788- codeline = this_line
27892789- break
27902790- end
27912791- bytes = (bytes + #newline + #this_line)
34643464+ local function sub(str, start, _end)
34653465+ if (_end < start) then
34663466+ return ""
34673467+ elseif utf8_ok_3f then
34683468+ return string.sub(str, utf8.offset(str, start), ((utf8.offset(str, (_end + 1)) or (utf8.len(str) + 1)) - 1))
34693469+ else
34703470+ return string.sub(str, start, math.min(_end, str:len()))
27923471 end
27932793- return codeline, bytes
27943472 end
27952795- local function read_line(filename, line, source)
27962796- if source then
27972797- return read_line_from_source(source, line)
34733473+ local function highlight_line(codeline, col, _3fendcol)
34743474+ local endcol = (_3fendcol or col)
34753475+ local eol
34763476+ if utf8_ok_3f then
34773477+ eol = utf8.len(codeline)
27983478 else
27992799- return read_line_from_file(filename, line)
34793479+ eol = string.len(codeline)
28003480 end
34813481+ return (sub(codeline, 1, col) .. "\27[7m" .. sub(codeline, (col + 1), (endcol + 1)) .. "\27[0m" .. sub(codeline, (endcol + 2), eol))
28013482 end
28022802- local function friendly_msg(msg, _0_0, source)
28032803- local _1_ = _0_0
28042804- local byteend = _1_["byteend"]
28052805- local bytestart = _1_["bytestart"]
28062806- local filename = _1_["filename"]
28072807- local line = _1_["line"]
28082808- local ok, codeline, bol = pcall(read_line, filename, line, source)
28092809- local suggestions0 = suggest(msg)
34833483+ local function friendly_msg(msg, _182_, source)
34843484+ local _arg_183_ = _182_
34853485+ local filename = _arg_183_["filename"]
34863486+ local line = _arg_183_["line"]
34873487+ local col = _arg_183_["col"]
34883488+ local endcol = _arg_183_["endcol"]
34893489+ local ok, codeline = pcall(read_line, filename, line, source)
28103490 local out = {msg, ""}
28113491 if (ok and codeline) then
28122812- table.insert(out, codeline)
34923492+ if col then
34933493+ table.insert(out, highlight_line(codeline, col, endcol))
34943494+ else
34953495+ table.insert(out, codeline)
34963496+ end
34973497+ else
28133498 end
28142814- if (ok and codeline and bytestart and byteend) then
28152815- table.insert(out, (string.rep(" ", (bytestart - bol - 1)) .. "^" .. string.rep("^", math.min((byteend - bytestart), ((bol + #codeline) - bytestart)))))
28162816- end
28172817- if (ok and codeline and bytestart and not byteend) then
28182818- table.insert(out, (string.rep("-", (bytestart - bol - 1)) .. "^"))
28192819- table.insert(out, "")
28202820- end
28212821- if suggestions0 then
28222822- for _, suggestion in ipairs(suggestions0) do
28232823- table.insert(out, ("* Try %s."):format(suggestion))
28242824- end
34993499+ for _, suggestion in ipairs((suggest(msg) or {})) do
35003500+ table.insert(out, ("* Try %s."):format(suggestion))
28253501 end
28263502 return table.concat(out, "\n")
28273503 end
28283504 local function assert_compile(condition, msg, ast, source)
28293505 if not condition then
28302830- local _1_ = ast_source(ast)
28312831- local filename = _1_["filename"]
28322832- local line = _1_["line"]
28332833- error(friendly_msg(("Compile error in %s:%s\n %s"):format((filename or "unknown"), (line or "?"), msg), ast_source(ast), source), 0)
35063506+ local _let_186_ = utils["ast-source"](ast)
35073507+ local filename = _let_186_["filename"]
35083508+ local line = _let_186_["line"]
35093509+ local col = _let_186_["col"]
35103510+ error(friendly_msg(("Compile error in %s:%s:%s\n %s"):format((filename or "unknown"), (line or "?"), (col or "?"), msg), utils["ast-source"](ast), source), 0)
35113511+ else
28343512 end
28353513 return condition
28363514 end
28372837- local function parse_error(msg, filename, line, bytestart, source)
28382838- return error(friendly_msg(("Parse error in %s:%s\n %s"):format(filename, line, msg), {bytestart = bytestart, filename = filename, line = line}, source), 0)
35153515+ local function parse_error(msg, filename, line, col, source)
35163516+ return error(friendly_msg(("Parse error in %s:%s:%s\n %s"):format(filename, line, col, msg), {filename = filename, line = line, col = col}, source), 0)
28393517 end
28403518 return {["assert-compile"] = assert_compile, ["parse-error"] = parse_error}
28413519end
···28453523 local unpack = (table.unpack or _G.unpack)
28463524 local function granulate(getchunk)
28473525 local c, index, done_3f = "", 1, false
28482848- local function _0_(parser_state)
35263526+ local function _188_(parser_state)
28493527 if not done_3f then
28503528 if (index <= #c) then
28513529 local b = c:byte(index)
28523530 index = (index + 1)
28533531 return b
28543532 else
28552855- local _1_0, _2_0, _3_0 = getchunk(parser_state)
28562856- local _4_
28572857- do
28582858- local char = _1_0
28592859- _4_ = ((nil ~= _1_0) and (char ~= ""))
35333533+ local _189_ = getchunk(parser_state)
35343534+ local function _190_()
35353535+ local char = _189_
35363536+ return (char ~= "")
28603537 end
28612861- if _4_ then
28622862- local char = _1_0
35383538+ if ((nil ~= _189_) and _190_()) then
35393539+ local char = _189_
28633540 c = char
28643541 index = 2
28653542 return c:byte()
28662866- else
28672867- local _ = _1_0
35433543+ elseif true then
35443544+ local _ = _189_
28683545 done_3f = true
28693546 return nil
35473547+ else
35483548+ return nil
28703549 end
28713550 end
35513551+ else
35523552+ return nil
28723553 end
28733554 end
28742874- local function _1_()
35553555+ local function _194_()
28753556 c = ""
28763557 return nil
28773558 end
28782878- return _0_, _1_
35593559+ return _188_, _194_
28793560 end
28803561 local function string_stream(str)
28813562 local str0 = str:gsub("^#!", ";;")
28823563 local index = 1
28832883- local function _0_()
35643564+ local function _195_()
28843565 local r = str0:byte(index)
28853566 index = (index + 1)
28863567 return r
28873568 end
28882888- return _0_
28892889- end
28902890- local delims = {[123] = 125, [125] = true, [40] = 41, [41] = true, [91] = 93, [93] = true}
28912891- local function whitespace_3f(b)
28922892- return ((b == 32) or ((b >= 9) and (b <= 13)))
35693569+ return _195_
28933570 end
35713571+ local delims = {[40] = 41, [41] = true, [91] = 93, [93] = true, [123] = 125, [125] = true}
28943572 local function sym_char_3f(b)
28952895- local b0 = nil
35733573+ local b0
28963574 if ("number" == type(b)) then
28973575 b0 = b
28983576 else
28993577 b0 = string.byte(b)
29003578 end
29012901- return ((b0 > 32) and not delims[b0] and (b0 ~= 127) and (b0 ~= 34) and (b0 ~= 39) and (b0 ~= 126) and (b0 ~= 59) and (b0 ~= 44) and (b0 ~= 64) and (b0 ~= 96))
35793579+ return ((32 < b0) and not delims[b0] and (b0 ~= 127) and (b0 ~= 34) and (b0 ~= 39) and (b0 ~= 126) and (b0 ~= 59) and (b0 ~= 44) and (b0 ~= 64) and (b0 ~= 96))
29023580 end
29033581 local prefixes = {[35] = "hashfn", [39] = "quote", [44] = "unquote", [96] = "quote"}
29042904- local function parser(getbyte, filename, options)
35823582+ local function char_starter_3f(b)
35833583+ return ((function(_197_,_198_,_199_) return (_197_ < _198_) and (_198_ < _199_) end)(1,b,127) or (function(_200_,_201_,_202_) return (_200_ < _201_) and (_201_ < _202_) end)(192,b,247))
35843584+ end
35853585+ local function parser_fn(getbyte, filename, _203_)
35863586+ local _arg_204_ = _203_
35873587+ local source = _arg_204_["source"]
35883588+ local unfriendly = _arg_204_["unfriendly"]
35893589+ local comments = _arg_204_["comments"]
35903590+ local options = _arg_204_
29053591 local stack = {}
29062906- local line = 1
29072907- local byteindex = 0
29082908- local lastb = nil
35923592+ local line, byteindex, col, prev_col, lastb = 1, 0, 0, 0, nil
29093593 local function ungetb(ub)
35943594+ if char_starter_3f(ub) then
35953595+ col = (col - 1)
35963596+ else
35973597+ end
29103598 if (ub == 10) then
29112911- line = (line - 1)
35993599+ line, col = (line - 1), prev_col
36003600+ else
29123601 end
29133602 byteindex = (byteindex - 1)
29143603 lastb = ub
···29223611 r = getbyte({["stack-size"] = #stack})
29233612 end
29243613 byteindex = (byteindex + 1)
36143614+ if (r and char_starter_3f(r)) then
36153615+ col = (col + 1)
36163616+ else
36173617+ end
29253618 if (r == 10) then
29262926- line = (line + 1)
36193619+ line, col, prev_col = (line + 1), 0, col
36203620+ else
29273621 end
29283622 return r
29293623 end
29302930- local function parse_error(msg, byteindex_override)
29312931- local _0_ = (options or utils.root.options or {})
29322932- local source = _0_["source"]
29332933- local unfriendly = _0_["unfriendly"]
29342934- utils.root.reset()
29352935- if unfriendly then
29362936- return error(string.format("Parse error in %s:%s: %s", (filename or "unknown"), (line or "?"), msg), 0)
36243624+ local function whitespace_3f(b)
36253625+ local function _214_()
36263626+ local t_213_ = options.whitespace
36273627+ if (nil ~= t_213_) then
36283628+ t_213_ = (t_213_)[b]
36293629+ else
36303630+ end
36313631+ return t_213_
36323632+ end
36333633+ return ((b == 32) or (function(_210_,_211_,_212_) return (_210_ <= _211_) and (_211_ <= _212_) end)(9,b,13) or _214_())
36343634+ end
36353635+ local function parse_error(msg, _3fcol_adjust)
36363636+ local col0 = (col + (_3fcol_adjust or -1))
36373637+ if (nil == utils["hook-opts"]("parse-error", options, msg, filename, (line or "?"), col0, source, utils.root.reset)) then
36383638+ utils.root.reset()
36393639+ if (unfriendly or not _G.io or not _G.io.read) then
36403640+ return error(string.format("%s:%s:%s Parse error: %s", filename, (line or "?"), col0, msg), 0)
36413641+ else
36423642+ return friend["parse-error"](msg, filename, (line or "?"), col0, source)
36433643+ end
29373644 else
29382938- return friend["parse-error"](msg, (filename or "unknown"), (line or "?"), (byteindex_override or byteindex), source)
36453645+ return nil
29393646 end
29403647 end
29413648 local function parse_stream()
29423649 local whitespace_since_dispatch, done_3f, retval = true
36503650+ local function set_source_fields(source0)
36513651+ source0.byteend, source0.endcol = byteindex, (col - 1)
36523652+ return nil
36533653+ end
29433654 local function dispatch(v)
29442944- local _0_0 = stack[#stack]
29452945- if (_0_0 == nil) then
36553655+ local _218_ = stack[#stack]
36563656+ if (_218_ == nil) then
29463657 retval, done_3f, whitespace_since_dispatch = v, true, false
29473658 return nil
29482948- elseif ((type(_0_0) == "table") and (nil ~= _0_0.prefix)) then
29492949- local prefix = _0_0.prefix
29502950- table.remove(stack)
29512951- return dispatch(utils.list(utils.sym(prefix), v))
29522952- elseif (nil ~= _0_0) then
29532953- local top = _0_0
36593659+ elseif ((_G.type(_218_) == "table") and (nil ~= (_218_).prefix)) then
36603660+ local prefix = (_218_).prefix
36613661+ local source0
36623662+ do
36633663+ local _219_ = table.remove(stack)
36643664+ set_source_fields(_219_)
36653665+ source0 = _219_
36663666+ end
36673667+ local list = utils.list(utils.sym(prefix, source0), v)
36683668+ for k, v0 in pairs(source0) do
36693669+ list[k] = v0
36703670+ end
36713671+ return dispatch(list)
36723672+ elseif (nil ~= _218_) then
36733673+ local top = _218_
29543674 whitespace_since_dispatch = false
29553675 return table.insert(top, v)
36763676+ else
36773677+ return nil
29563678 end
29573679 end
29583680 local function badend()
29593681 local accum = utils.map(stack, "closer")
29602960- local _0_
36823682+ local _221_
29613683 if (#stack == 1) then
29622962- _0_ = ""
36843684+ _221_ = ""
29633685 else
29642964- _0_ = "s"
36863686+ _221_ = "s"
29653687 end
29662966- return parse_error(string.format("expected closing delimiter%s %s", _0_, string.char(unpack(accum))))
36883688+ return parse_error(string.format("expected closing delimiter%s %s", _221_, string.char(unpack(accum))))
29673689 end
29683690 local function skip_whitespace(b)
29693691 if (b and whitespace_3f(b)) then
29703692 whitespace_since_dispatch = true
29713693 return skip_whitespace(getb())
29722972- elseif (not b and (#stack > 0)) then
36943694+ elseif (not b and (0 < #stack)) then
29733695 return badend()
29743696 else
29753697 return b
···29773699 end
29783700 local function parse_comment(b, contents)
29793701 if (b and (10 ~= b)) then
29802980- local function _1_()
29812981- local _0_0 = contents
29822982- table.insert(_0_0, string.char(b))
29832983- return _0_0
37023702+ local function _225_()
37033703+ local _224_ = contents
37043704+ table.insert(_224_, string.char(b))
37053705+ return _224_
29843706 end
29852985- return parse_comment(getb(), _1_())
29862986- elseif (options and options.comments) then
29872987- return dispatch(utils.comment(table.concat(contents)))
37073707+ return parse_comment(getb(), _225_())
37083708+ elseif comments then
37093709+ ungetb(10)
37103710+ return dispatch(utils.comment(table.concat(contents), {line = (line - 1), filename = filename}))
29883711 else
29892989- return b
37123712+ return nil
29903713 end
29913714 end
29923715 local function open_table(b)
29933716 if not whitespace_since_dispatch then
29943717 parse_error(("expected whitespace before opening delimiter " .. string.char(b)))
37183718+ else
29953719 end
29962996- return table.insert(stack, {bytestart = byteindex, closer = delims[b], filename = filename, line = line})
37203720+ return table.insert(stack, {bytestart = byteindex, closer = delims[b], filename = filename, line = line, col = (col - 1)})
29973721 end
29983722 local function close_list(list)
29993723 return dispatch(setmetatable(list, getmetatable(utils.list())))
···30053729 end
30063730 return dispatch(val)
30073731 end
37323732+ local function add_comment_at(comments0, index, node)
37333733+ local _228_ = (comments0)[index]
37343734+ if (nil ~= _228_) then
37353735+ local existing = _228_
37363736+ return table.insert(existing, node)
37373737+ elseif true then
37383738+ local _ = _228_
37393739+ comments0[index] = {node}
37403740+ return nil
37413741+ else
37423742+ return nil
37433743+ end
37443744+ end
37453745+ local function next_noncomment(tbl, i)
37463746+ if utils["comment?"](tbl[i]) then
37473747+ return next_noncomment(tbl, (i + 1))
37483748+ else
37493749+ return tbl[i]
37503750+ end
37513751+ end
37523752+ local function extract_comments(tbl)
37533753+ local comments0 = {keys = {}, values = {}, last = {}}
37543754+ while utils["comment?"](tbl[#tbl]) do
37553755+ table.insert(comments0.last, 1, table.remove(tbl))
37563756+ end
37573757+ local last_key_3f = false
37583758+ for i, node in ipairs(tbl) do
37593759+ if not utils["comment?"](node) then
37603760+ last_key_3f = not last_key_3f
37613761+ elseif last_key_3f then
37623762+ add_comment_at(comments0.values, next_noncomment(tbl, i), node)
37633763+ else
37643764+ add_comment_at(comments0.keys, next_noncomment(tbl, i), node)
37653765+ end
37663766+ end
37673767+ for i = #tbl, 1, -1 do
37683768+ if utils["comment?"](tbl[i]) then
37693769+ table.remove(tbl, i)
37703770+ else
37713771+ end
37723772+ end
37733773+ return comments0
37743774+ end
30083775 local function close_curly_table(tbl)
37763776+ local comments0 = extract_comments(tbl)
37773777+ local keys = {}
30093778 local val = {}
30103779 if ((#tbl % 2) ~= 0) then
30113780 byteindex = (byteindex - 1)
30123781 parse_error("expected even number of values in table literal")
37823782+ else
30133783 end
30143784 setmetatable(val, tbl)
30153785 for i = 1, #tbl, 2 do
30163786 if ((tostring(tbl[i]) == ":") and utils["sym?"](tbl[(i + 1)]) and utils["sym?"](tbl[i])) then
30173787 tbl[i] = tostring(tbl[(i + 1)])
37883788+ else
30183789 end
30193790 val[tbl[i]] = tbl[(i + 1)]
37913791+ table.insert(keys, tbl[i])
30203792 end
37933793+ tbl.comments = comments0
37943794+ tbl.keys = keys
30213795 return dispatch(val)
30223796 end
30233797 local function close_table(b)
30243798 local top = table.remove(stack)
30253799 if (top == nil) then
30263800 parse_error(("unexpected closing delimiter " .. string.char(b)))
38013801+ else
30273802 end
30283028- if (top.closer ~= b) then
38033803+ if (top.closer and (top.closer ~= b)) then
30293804 parse_error(("mismatched closing delimiter " .. string.char(b) .. ", expected " .. string.char(top.closer)))
38053805+ else
30303806 end
30313031- top.byteend = byteindex
38073807+ set_source_fields(top)
30323808 if (b == 41) then
30333809 return close_list(top)
30343810 elseif (b == 93) then
···30393815 end
30403816 local function parse_string_loop(chars, b, state)
30413817 table.insert(chars, b)
30423042- local state0 = nil
38183818+ local state0
30433819 do
30443044- local _0_0 = {state, b}
30453045- if ((type(_0_0) == "table") and (_0_0[1] == "base") and (_0_0[2] == 92)) then
38203820+ local _238_ = {state, b}
38213821+ if ((_G.type(_238_) == "table") and ((_238_)[1] == "base") and ((_238_)[2] == 92)) then
30463822 state0 = "backslash"
30473047- elseif ((type(_0_0) == "table") and (_0_0[1] == "base") and (_0_0[2] == 34)) then
38233823+ elseif ((_G.type(_238_) == "table") and ((_238_)[1] == "base") and ((_238_)[2] == 34)) then
30483824 state0 = "done"
30493049- else
30503050- local _ = _0_0
38253825+ elseif ((_G.type(_238_) == "table") and ((_238_)[1] == "backslash") and ((_238_)[2] == 10)) then
38263826+ table.remove(chars, (#chars - 1))
30513827 state0 = "base"
38283828+ elseif true then
38293829+ local _ = _238_
38303830+ state0 = "base"
38313831+ else
38323832+ state0 = nil
30523833 end
30533834 end
30543835 if (b and (state0 ~= "done")) then
···30583839 end
30593840 end
30603841 local function escape_char(c)
30613061- return ({[10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r", [7] = "\\a", [8] = "\\b", [9] = "\\t"})[c:byte()]
38423842+ return ({[7] = "\\a", [8] = "\\b", [9] = "\\t", [10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r"})[c:byte()]
30623843 end
30633844 local function parse_string()
30643845 table.insert(stack, {closer = 34})
30653846 local chars = {34}
30663847 if not parse_string_loop(chars, getb(), "base") then
30673848 badend()
38493849+ else
30683850 end
30693851 table.remove(stack)
30703852 local raw = string.char(unpack(chars))
30713853 local formatted = raw:gsub("[\7-\13]", escape_char)
30723072- local load_fn = (rawget(_G, "loadstring") or load)(("return " .. formatted))
30733073- return dispatch(load_fn())
38543854+ local _242_ = (rawget(_G, "loadstring") or load)(("return " .. formatted))
38553855+ if (nil ~= _242_) then
38563856+ local load_fn = _242_
38573857+ return dispatch(load_fn())
38583858+ elseif (_242_ == nil) then
38593859+ return parse_error(("Invalid string: " .. raw))
38603860+ else
38613861+ return nil
38623862+ end
30743863 end
30753864 local function parse_prefix(b)
30763076- table.insert(stack, {prefix = prefixes[b]})
38653865+ table.insert(stack, {prefix = prefixes[b], filename = filename, line = line, bytestart = byteindex, col = (col - 1)})
30773866 local nextb = getb()
30783078- if whitespace_3f(nextb) then
38673867+ if (whitespace_3f(nextb) or (true == delims[nextb])) then
30793868 if (b ~= 35) then
30803869 parse_error("invalid whitespace after quoting prefix")
38703870+ else
30813871 end
30823872 table.remove(stack)
30833873 dispatch(utils.sym("#"))
38743874+ else
30843875 end
30853876 return ungetb(nextb)
30863877 end
···30913882 else
30923883 if b then
30933884 ungetb(b)
38853885+ else
30943886 end
30953887 return chars
30963888 end
···31013893 dispatch((tonumber(number_with_stripped_underscores) or parse_error(("could not read number \"" .. rawstr .. "\""))))
31023894 return true
31033895 else
31043104- local _0_0 = tonumber(number_with_stripped_underscores)
31053105- if (nil ~= _0_0) then
31063106- local x = _0_0
38963896+ local _248_ = tonumber(number_with_stripped_underscores)
38973897+ if (nil ~= _248_) then
38983898+ local x = _248_
31073899 dispatch(x)
31083900 return true
39013901+ elseif true then
39023902+ local _ = _248_
39033903+ return false
31093904 else
31103110- local _ = _0_0
31113111- return false
39053905+ return nil
31123906 end
31133907 end
31143908 end
31153909 local function check_malformed_sym(rawstr)
39103910+ local function col_adjust(pat)
39113911+ return (rawstr:find(pat) - utils.len(rawstr) - 1)
39123912+ end
31163913 if (rawstr:match("^~") and (rawstr ~= "~=")) then
31173117- return parse_error("illegal character: ~")
39143914+ return parse_error("invalid character: ~")
31183915 elseif rawstr:match("%.[0-9]") then
31193119- return parse_error(("can't start multisym segment " .. "with a digit: " .. rawstr), (((byteindex - #rawstr) + rawstr:find("%.[0-9]")) + 1))
39163916+ return parse_error(("can't start multisym segment with a digit: " .. rawstr), col_adjust("%.[0-9]"))
31203917 elseif (rawstr:match("[%.:][%.:]") and (rawstr ~= "..") and (rawstr ~= "$...")) then
31213121- return parse_error(("malformed multisym: " .. rawstr), ((byteindex - #rawstr) + 1 + rawstr:find("[%.:][%.:]")))
39183918+ return parse_error(("malformed multisym: " .. rawstr), col_adjust("[%.:][%.:]"))
39193919+ elseif ((rawstr ~= ":") and rawstr:match(":$")) then
39203920+ return parse_error(("malformed multisym: " .. rawstr), col_adjust(":$"))
31223921 elseif rawstr:match(":.+[%.:]") then
31233123- return parse_error(("method must be last component " .. "of multisym: " .. rawstr), ((byteindex - #rawstr) + rawstr:find(":.+[%.:]")))
39223922+ return parse_error(("method must be last component of multisym: " .. rawstr), col_adjust(":.+[%.:]"))
39233923+ else
39243924+ return rawstr
31243925 end
31253926 end
31263927 local function parse_sym(b)
31273127- local bytestart = byteindex
39283928+ local source0 = {bytestart = byteindex, filename = filename, line = line, col = (col - 1)}
31283929 local rawstr = string.char(unpack(parse_sym_loop({b}, getb())))
39303930+ set_source_fields(source0)
31293931 if (rawstr == "true") then
31303932 return dispatch(true)
31313933 elseif (rawstr == "false") then
31323934 return dispatch(false)
31333935 elseif (rawstr == "...") then
31343134- return dispatch(utils.varg())
39363936+ return dispatch(utils.varg(source0))
31353937 elseif rawstr:match("^:.+$") then
31363938 return dispatch(rawstr:sub(2))
31373137- elseif parse_number(rawstr) then
31383138- return nil
31393139- elseif check_malformed_sym(rawstr) then
39393939+ elseif not parse_number(rawstr) then
39403940+ return dispatch(utils.sym(check_malformed_sym(rawstr), source0))
39413941+ else
31403942 return nil
31413141- else
31423142- return dispatch(utils.sym(rawstr, nil, {byteend = byteindex, bytestart = bytestart, filename = filename, line = line}))
31433943 end
31443944 end
31453945 local function parse_loop(b)
···31563956 parse_prefix(b)
31573957 elseif (sym_char_3f(b) or (b == string.byte("~"))) then
31583958 parse_sym(b)
39593959+ elseif not utils["hook-opts"]("illegal-char", options, b, getb, ungetb, dispatch) then
39603960+ parse_error(("invalid character: " .. string.char(b)))
31593961 else
31603160- parse_error(("illegal character: " .. string.char(b)))
31613962 end
31623963 if not b then
31633964 return nil
···31693970 end
31703971 return parse_loop(skip_whitespace(getb()))
31713972 end
31723172- local function _0_()
31733173- stack = {}
39733973+ local function _255_()
39743974+ stack, line, byteindex, col, lastb = {}, 1, 0, 0, nil
31743975 return nil
31753976 end
31763176- return parse_stream, _0_
39773977+ return parse_stream, _255_
31773978 end
31783178- return {["string-stream"] = string_stream, ["sym-char?"] = sym_char_3f, granulate = granulate, parser = parser}
39793979+ local function parser(stream_or_string, _3ffilename, _3foptions)
39803980+ local filename = (_3ffilename or "unknown")
39813981+ local options = (_3foptions or utils.root.options or {})
39823982+ assert(("string" == type(filename)), "expected filename as second argument to parser")
39833983+ if ("string" == type(stream_or_string)) then
39843984+ return parser_fn(string_stream(stream_or_string), filename, options)
39853985+ else
39863986+ return parser_fn(stream_or_string, filename, options)
39873987+ end
39883988+ end
39893989+ return {granulate = granulate, parser = parser, ["string-stream"] = string_stream, ["sym-char?"] = sym_char_3f}
31793990end
31803180-local utils = nil
39913991+local utils
39923992+package.preload["fennel.view"] = package.preload["fennel.view"] or function(...)
39933993+ local type_order = {number = 1, boolean = 2, string = 3, table = 4, ["function"] = 5, userdata = 6, thread = 7}
39943994+ local lua_pairs = pairs
39953995+ local lua_ipairs = ipairs
39963996+ local function pairs(t)
39973997+ local _1_ = getmetatable(t)
39983998+ if ((_G.type(_1_) == "table") and (nil ~= (_1_).__pairs)) then
39993999+ local p = (_1_).__pairs
40004000+ return p(t)
40014001+ elseif true then
40024002+ local _ = _1_
40034003+ return lua_pairs(t)
40044004+ else
40054005+ return nil
40064006+ end
40074007+ end
40084008+ local function ipairs(t)
40094009+ local _3_ = getmetatable(t)
40104010+ if ((_G.type(_3_) == "table") and (nil ~= (_3_).__ipairs)) then
40114011+ local i = (_3_).__ipairs
40124012+ return i(t)
40134013+ elseif true then
40144014+ local _ = _3_
40154015+ return lua_ipairs(t)
40164016+ else
40174017+ return nil
40184018+ end
40194019+ end
40204020+ local function length_2a(t)
40214021+ local _5_ = getmetatable(t)
40224022+ if ((_G.type(_5_) == "table") and (nil ~= (_5_).__len)) then
40234023+ local l = (_5_).__len
40244024+ return l(t)
40254025+ elseif true then
40264026+ local _ = _5_
40274027+ return #t
40284028+ else
40294029+ return nil
40304030+ end
40314031+ end
40324032+ local function sort_keys(_7_, _9_)
40334033+ local _arg_8_ = _7_
40344034+ local a = _arg_8_[1]
40354035+ local _arg_10_ = _9_
40364036+ local b = _arg_10_[1]
40374037+ local ta = type(a)
40384038+ local tb = type(b)
40394039+ if ((ta == tb) and ((ta == "string") or (ta == "number"))) then
40404040+ return (a < b)
40414041+ else
40424042+ local dta = type_order[ta]
40434043+ local dtb = type_order[tb]
40444044+ if (dta and dtb) then
40454045+ return (dta < dtb)
40464046+ elseif dta then
40474047+ return true
40484048+ elseif dtb then
40494049+ return false
40504050+ else
40514051+ return (ta < tb)
40524052+ end
40534053+ end
40544054+ end
40554055+ local function max_index_gap(kv)
40564056+ local gap = 0
40574057+ if (0 < length_2a(kv)) then
40584058+ local i = 0
40594059+ for _, _13_ in ipairs(kv) do
40604060+ local _each_14_ = _13_
40614061+ local k = _each_14_[1]
40624062+ if (gap < (k - i)) then
40634063+ gap = (k - i)
40644064+ else
40654065+ end
40664066+ i = k
40674067+ end
40684068+ else
40694069+ end
40704070+ return gap
40714071+ end
40724072+ local function fill_gaps(kv)
40734073+ local missing_indexes = {}
40744074+ local i = 0
40754075+ for _, _17_ in ipairs(kv) do
40764076+ local _each_18_ = _17_
40774077+ local j = _each_18_[1]
40784078+ i = (i + 1)
40794079+ while (i < j) do
40804080+ table.insert(missing_indexes, i)
40814081+ i = (i + 1)
40824082+ end
40834083+ end
40844084+ for _, k in ipairs(missing_indexes) do
40854085+ table.insert(kv, k, {k})
40864086+ end
40874087+ return nil
40884088+ end
40894089+ local function table_kv_pairs(t, options)
40904090+ local assoc_3f = false
40914091+ local kv = {}
40924092+ local insert = table.insert
40934093+ for k, v in pairs(t) do
40944094+ if ((type(k) ~= "number") or (k < 1)) then
40954095+ assoc_3f = true
40964096+ else
40974097+ end
40984098+ insert(kv, {k, v})
40994099+ end
41004100+ table.sort(kv, sort_keys)
41014101+ if not assoc_3f then
41024102+ if (options["max-sparse-gap"] < max_index_gap(kv)) then
41034103+ assoc_3f = true
41044104+ else
41054105+ fill_gaps(kv)
41064106+ end
41074107+ else
41084108+ end
41094109+ if (length_2a(kv) == 0) then
41104110+ return kv, "empty"
41114111+ else
41124112+ local function _22_()
41134113+ if assoc_3f then
41144114+ return "table"
41154115+ else
41164116+ return "seq"
41174117+ end
41184118+ end
41194119+ return kv, _22_()
41204120+ end
41214121+ end
41224122+ local function count_table_appearances(t, appearances)
41234123+ if (type(t) == "table") then
41244124+ if not appearances[t] then
41254125+ appearances[t] = 1
41264126+ for k, v in pairs(t) do
41274127+ count_table_appearances(k, appearances)
41284128+ count_table_appearances(v, appearances)
41294129+ end
41304130+ else
41314131+ appearances[t] = ((appearances[t] or 0) + 1)
41324132+ end
41334133+ else
41344134+ end
41354135+ return appearances
41364136+ end
41374137+ local function save_table(t, seen)
41384138+ local seen0 = (seen or {len = 0})
41394139+ local id = (seen0.len + 1)
41404140+ if not (seen0)[t] then
41414141+ seen0[t] = id
41424142+ seen0.len = id
41434143+ else
41444144+ end
41454145+ return seen0
41464146+ end
41474147+ local function detect_cycle(t, seen, _3fk)
41484148+ if ("table" == type(t)) then
41494149+ seen[t] = true
41504150+ local _27_, _28_ = next(t, _3fk)
41514151+ if ((nil ~= _27_) and (nil ~= _28_)) then
41524152+ local k = _27_
41534153+ local v = _28_
41544154+ return (seen[k] or detect_cycle(k, seen) or seen[v] or detect_cycle(v, seen) or detect_cycle(t, seen, k))
41554155+ else
41564156+ return nil
41574157+ end
41584158+ else
41594159+ return nil
41604160+ end
41614161+ end
41624162+ local function visible_cycle_3f(t, options)
41634163+ return (options["detect-cycles?"] and detect_cycle(t, {}) and save_table(t, options.seen) and (1 < (options.appearances[t] or 0)))
41644164+ end
41654165+ local function table_indent(indent, id)
41664166+ local opener_length
41674167+ if id then
41684168+ opener_length = (length_2a(tostring(id)) + 2)
41694169+ else
41704170+ opener_length = 1
41714171+ end
41724172+ return (indent + opener_length)
41734173+ end
41744174+ local pp = nil
41754175+ local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix, last_comment_3f)
41764176+ local indent_str = ("\n" .. string.rep(" ", indent))
41774177+ local open
41784178+ local function _32_()
41794179+ if ("seq" == table_type) then
41804180+ return "["
41814181+ else
41824182+ return "{"
41834183+ end
41844184+ end
41854185+ open = ((prefix or "") .. _32_())
41864186+ local close
41874187+ if ("seq" == table_type) then
41884188+ close = "]"
41894189+ else
41904190+ close = "}"
41914191+ end
41924192+ local oneline = (open .. table.concat(elements, " ") .. close)
41934193+ if (not options["one-line?"] and (multiline_3f or (options["line-length"] < (indent + length_2a(oneline))) or last_comment_3f)) then
41944194+ local function _34_()
41954195+ if last_comment_3f then
41964196+ return indent_str
41974197+ else
41984198+ return ""
41994199+ end
42004200+ end
42014201+ return (open .. table.concat(elements, indent_str) .. _34_() .. close)
42024202+ else
42034203+ return oneline
42044204+ end
42054205+ end
42064206+ local function utf8_len(x)
42074207+ local n = 0
42084208+ for _ in string.gmatch(x, "[%z\1-\127\192-\247]") do
42094209+ n = (n + 1)
42104210+ end
42114211+ return n
42124212+ end
42134213+ local function comment_3f(x)
42144214+ if ("table" == type(x)) then
42154215+ local fst = x[1]
42164216+ return (("string" == type(fst)) and (nil ~= fst:find("^;")))
42174217+ else
42184218+ return false
42194219+ end
42204220+ end
42214221+ local function pp_associative(t, kv, options, indent)
42224222+ local multiline_3f = false
42234223+ local id = options.seen[t]
42244224+ if (options.depth <= options.level) then
42254225+ return "{...}"
42264226+ elseif (id and options["detect-cycles?"]) then
42274227+ return ("@" .. id .. "{...}")
42284228+ else
42294229+ local visible_cycle_3f0 = visible_cycle_3f(t, options)
42304230+ local id0 = (visible_cycle_3f0 and options.seen[t])
42314231+ local indent0 = table_indent(indent, id0)
42324232+ local slength
42334233+ if options["utf8?"] then
42344234+ slength = utf8_len
42354235+ else
42364236+ local function _37_(_241)
42374237+ return #_241
42384238+ end
42394239+ slength = _37_
42404240+ end
42414241+ local prefix
42424242+ if visible_cycle_3f0 then
42434243+ prefix = ("@" .. id0)
42444244+ else
42454245+ prefix = ""
42464246+ end
42474247+ local items
42484248+ do
42494249+ local tbl_14_auto = {}
42504250+ local i_15_auto = #tbl_14_auto
42514251+ for _, _40_ in ipairs(kv) do
42524252+ local _each_41_ = _40_
42534253+ local k = _each_41_[1]
42544254+ local v = _each_41_[2]
42554255+ local val_16_auto
42564256+ do
42574257+ local k0 = pp(k, options, (indent0 + 1), true)
42584258+ local v0 = pp(v, options, (indent0 + slength(k0) + 1))
42594259+ multiline_3f = (multiline_3f or k0:find("\n") or v0:find("\n"))
42604260+ val_16_auto = (k0 .. " " .. v0)
42614261+ end
42624262+ if (nil ~= val_16_auto) then
42634263+ i_15_auto = (i_15_auto + 1)
42644264+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
42654265+ else
42664266+ end
42674267+ end
42684268+ items = tbl_14_auto
42694269+ end
42704270+ return concat_table_lines(items, options, multiline_3f, indent0, "table", prefix, false)
42714271+ end
42724272+ end
42734273+ local function pp_sequence(t, kv, options, indent)
42744274+ local multiline_3f = false
42754275+ local id = options.seen[t]
42764276+ if (options.depth <= options.level) then
42774277+ return "[...]"
42784278+ elseif (id and options["detect-cycles?"]) then
42794279+ return ("@" .. id .. "[...]")
42804280+ else
42814281+ local visible_cycle_3f0 = visible_cycle_3f(t, options)
42824282+ local id0 = (visible_cycle_3f0 and options.seen[t])
42834283+ local indent0 = table_indent(indent, id0)
42844284+ local prefix
42854285+ if visible_cycle_3f0 then
42864286+ prefix = ("@" .. id0)
42874287+ else
42884288+ prefix = ""
42894289+ end
42904290+ local last_comment_3f = comment_3f(t[#t])
42914291+ local items
42924292+ do
42934293+ local tbl_14_auto = {}
42944294+ local i_15_auto = #tbl_14_auto
42954295+ for _, _45_ in ipairs(kv) do
42964296+ local _each_46_ = _45_
42974297+ local _0 = _each_46_[1]
42984298+ local v = _each_46_[2]
42994299+ local val_16_auto
43004300+ do
43014301+ local v0 = pp(v, options, indent0)
43024302+ multiline_3f = (multiline_3f or v0:find("\n") or v0:find("^;"))
43034303+ val_16_auto = v0
43044304+ end
43054305+ if (nil ~= val_16_auto) then
43064306+ i_15_auto = (i_15_auto + 1)
43074307+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
43084308+ else
43094309+ end
43104310+ end
43114311+ items = tbl_14_auto
43124312+ end
43134313+ return concat_table_lines(items, options, multiline_3f, indent0, "seq", prefix, last_comment_3f)
43144314+ end
43154315+ end
43164316+ local function concat_lines(lines, options, indent, force_multi_line_3f)
43174317+ if (length_2a(lines) == 0) then
43184318+ if options["empty-as-sequence?"] then
43194319+ return "[]"
43204320+ else
43214321+ return "{}"
43224322+ end
43234323+ else
43244324+ local oneline
43254325+ local _50_
43264326+ do
43274327+ local tbl_14_auto = {}
43284328+ local i_15_auto = #tbl_14_auto
43294329+ for _, line in ipairs(lines) do
43304330+ local val_16_auto = line:gsub("^%s+", "")
43314331+ if (nil ~= val_16_auto) then
43324332+ i_15_auto = (i_15_auto + 1)
43334333+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
43344334+ else
43354335+ end
43364336+ end
43374337+ _50_ = tbl_14_auto
43384338+ end
43394339+ oneline = table.concat(_50_, " ")
43404340+ if (not options["one-line?"] and (force_multi_line_3f or oneline:find("\n") or (options["line-length"] < (indent + length_2a(oneline))))) then
43414341+ return table.concat(lines, ("\n" .. string.rep(" ", indent)))
43424342+ else
43434343+ return oneline
43444344+ end
43454345+ end
43464346+ end
43474347+ local function pp_metamethod(t, metamethod, options, indent)
43484348+ if (options.depth <= options.level) then
43494349+ if options["empty-as-sequence?"] then
43504350+ return "[...]"
43514351+ else
43524352+ return "{...}"
43534353+ end
43544354+ else
43554355+ local _
43564356+ local function _55_(_241)
43574357+ return visible_cycle_3f(_241, options)
43584358+ end
43594359+ options["visible-cycle?"] = _55_
43604360+ _ = nil
43614361+ local lines, force_multi_line_3f = metamethod(t, pp, options, indent)
43624362+ options["visible-cycle?"] = nil
43634363+ local _56_ = type(lines)
43644364+ if (_56_ == "string") then
43654365+ return lines
43664366+ elseif (_56_ == "table") then
43674367+ return concat_lines(lines, options, indent, force_multi_line_3f)
43684368+ elseif true then
43694369+ local _0 = _56_
43704370+ return error("__fennelview metamethod must return a table of lines")
43714371+ else
43724372+ return nil
43734373+ end
43744374+ end
43754375+ end
43764376+ local function pp_table(x, options, indent)
43774377+ options.level = (options.level + 1)
43784378+ local x0
43794379+ do
43804380+ local _59_
43814381+ if options["metamethod?"] then
43824382+ local _60_ = x
43834383+ if (nil ~= _60_) then
43844384+ local _61_ = getmetatable(_60_)
43854385+ if (nil ~= _61_) then
43864386+ _59_ = (_61_).__fennelview
43874387+ else
43884388+ _59_ = _61_
43894389+ end
43904390+ else
43914391+ _59_ = _60_
43924392+ end
43934393+ else
43944394+ _59_ = nil
43954395+ end
43964396+ if (nil ~= _59_) then
43974397+ local metamethod = _59_
43984398+ x0 = pp_metamethod(x, metamethod, options, indent)
43994399+ elseif true then
44004400+ local _ = _59_
44014401+ local _65_, _66_ = table_kv_pairs(x, options)
44024402+ if (true and (_66_ == "empty")) then
44034403+ local _0 = _65_
44044404+ if options["empty-as-sequence?"] then
44054405+ x0 = "[]"
44064406+ else
44074407+ x0 = "{}"
44084408+ end
44094409+ elseif ((nil ~= _65_) and (_66_ == "table")) then
44104410+ local kv = _65_
44114411+ x0 = pp_associative(x, kv, options, indent)
44124412+ elseif ((nil ~= _65_) and (_66_ == "seq")) then
44134413+ local kv = _65_
44144414+ x0 = pp_sequence(x, kv, options, indent)
44154415+ else
44164416+ x0 = nil
44174417+ end
44184418+ else
44194419+ x0 = nil
44204420+ end
44214421+ end
44224422+ options.level = (options.level - 1)
44234423+ return x0
44244424+ end
44254425+ local function number__3estring(n)
44264426+ local _70_ = string.gsub(tostring(n), ",", ".")
44274427+ return _70_
44284428+ end
44294429+ local function colon_string_3f(s)
44304430+ return s:find("^[-%w?^_!$%&*+./@|<=>]+$")
44314431+ end
44324432+ local utf8_inits = {{["min-byte"] = 0, ["max-byte"] = 127, ["min-code"] = 0, ["max-code"] = 127, len = 1}, {["min-byte"] = 192, ["max-byte"] = 223, ["min-code"] = 128, ["max-code"] = 2047, len = 2}, {["min-byte"] = 224, ["max-byte"] = 239, ["min-code"] = 2048, ["max-code"] = 65535, len = 3}, {["min-byte"] = 240, ["max-byte"] = 247, ["min-code"] = 65536, ["max-code"] = 1114111, len = 4}}
44334433+ local function utf8_escape(str)
44344434+ local function validate_utf8(str0, index)
44354435+ local inits = utf8_inits
44364436+ local byte = string.byte(str0, index)
44374437+ local init
44384438+ do
44394439+ local ret = nil
44404440+ for _, init0 in ipairs(inits) do
44414441+ if ret then break end
44424442+ ret = (byte and (function(_71_,_72_,_73_) return (_71_ <= _72_) and (_72_ <= _73_) end)(init0["min-byte"],byte,init0["max-byte"]) and init0)
44434443+ end
44444444+ init = ret
44454445+ end
44464446+ local code
44474447+ local function _74_()
44484448+ local code0
44494449+ if init then
44504450+ code0 = (byte - init["min-byte"])
44514451+ else
44524452+ code0 = nil
44534453+ end
44544454+ for i = (index + 1), (index + init.len + -1) do
44554455+ local byte0 = string.byte(str0, i)
44564456+ code0 = (byte0 and code0 and (function(_76_,_77_,_78_) return (_76_ <= _77_) and (_77_ <= _78_) end)(128,byte0,191) and ((code0 * 64) + (byte0 - 128)))
44574457+ end
44584458+ return code0
44594459+ end
44604460+ code = (init and _74_())
44614461+ if (code and (function(_79_,_80_,_81_) return (_79_ <= _80_) and (_80_ <= _81_) end)(init["min-code"],code,init["max-code"]) and not (function(_82_,_83_,_84_) return (_82_ <= _83_) and (_83_ <= _84_) end)(55296,code,57343)) then
44624462+ return init.len
44634463+ else
44644464+ return nil
44654465+ end
44664466+ end
44674467+ local index = 1
44684468+ local output = {}
44694469+ while (index <= #str) do
44704470+ local nexti = (string.find(str, "[\128-\255]", index) or (#str + 1))
44714471+ local len = validate_utf8(str, nexti)
44724472+ table.insert(output, string.sub(str, index, (nexti + (len or 0) + -1)))
44734473+ if (not len and (nexti <= #str)) then
44744474+ table.insert(output, string.format("\\%03d", string.byte(str, nexti)))
44754475+ else
44764476+ end
44774477+ if len then
44784478+ index = (nexti + len)
44794479+ else
44804480+ index = (nexti + 1)
44814481+ end
44824482+ end
44834483+ return table.concat(output)
44844484+ end
44854485+ local function pp_string(str, options, indent)
44864486+ local escs
44874487+ local _88_
44884488+ if (options["escape-newlines?"] and (length_2a(str) < (options["line-length"] - indent))) then
44894489+ _88_ = "\\n"
44904490+ else
44914491+ _88_ = "\n"
44924492+ end
44934493+ local function _90_(_241, _242)
44944494+ return ("\\%03d"):format(_242:byte())
44954495+ end
44964496+ escs = setmetatable({["\7"] = "\\a", ["\8"] = "\\b", ["\12"] = "\\f", ["\11"] = "\\v", ["\13"] = "\\r", ["\9"] = "\\t", ["\\"] = "\\\\", ["\""] = "\\\"", ["\n"] = _88_}, {__index = _90_})
44974497+ local str0 = ("\"" .. str:gsub("[%c\\\"]", escs) .. "\"")
44984498+ if options["utf8?"] then
44994499+ return utf8_escape(str0)
45004500+ else
45014501+ return str0
45024502+ end
45034503+ end
45044504+ local function make_options(t, options)
45054505+ local defaults = {["line-length"] = 80, ["one-line?"] = false, depth = 128, ["detect-cycles?"] = true, ["empty-as-sequence?"] = false, ["metamethod?"] = true, ["prefer-colon?"] = false, ["escape-newlines?"] = false, ["utf8?"] = true, ["max-sparse-gap"] = 10}
45064506+ local overrides = {level = 0, appearances = count_table_appearances(t, {}), seen = {len = 0}}
45074507+ for k, v in pairs((options or {})) do
45084508+ defaults[k] = v
45094509+ end
45104510+ for k, v in pairs(overrides) do
45114511+ defaults[k] = v
45124512+ end
45134513+ return defaults
45144514+ end
45154515+ local function _92_(x, options, indent, colon_3f)
45164516+ local indent0 = (indent or 0)
45174517+ local options0 = (options or make_options(x))
45184518+ local x0
45194519+ if options0.preprocess then
45204520+ x0 = options0.preprocess(x, options0)
45214521+ else
45224522+ x0 = x
45234523+ end
45244524+ local tv = type(x0)
45254525+ local function _95_()
45264526+ local _94_ = getmetatable(x0)
45274527+ if (nil ~= _94_) then
45284528+ return (_94_).__fennelview
45294529+ else
45304530+ return _94_
45314531+ end
45324532+ end
45334533+ if ((tv == "table") or ((tv == "userdata") and _95_())) then
45344534+ return pp_table(x0, options0, indent0)
45354535+ elseif (tv == "number") then
45364536+ return number__3estring(x0)
45374537+ else
45384538+ local function _97_()
45394539+ if (colon_3f ~= nil) then
45404540+ return colon_3f
45414541+ elseif ("function" == type(options0["prefer-colon?"])) then
45424542+ return options0["prefer-colon?"](x0)
45434543+ else
45444544+ return options0["prefer-colon?"]
45454545+ end
45464546+ end
45474547+ if ((tv == "string") and colon_string_3f(x0) and _97_()) then
45484548+ return (":" .. x0)
45494549+ elseif (tv == "string") then
45504550+ return pp_string(x0, options0, indent0)
45514551+ elseif ((tv == "boolean") or (tv == "nil")) then
45524552+ return tostring(x0)
45534553+ else
45544554+ return ("#<" .. tostring(x0) .. ">")
45554555+ end
45564556+ end
45574557+ end
45584558+ pp = _92_
45594559+ local function view(x, _3foptions)
45604560+ return pp(x, make_options(x, _3foptions), 0)
45614561+ end
45624562+ return view
45634563+end
31814564package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(...)
31823182- local function stablepairs(t)
31833183- local keys = {}
31843184- local succ = {}
45654565+ local view = require("fennel.view")
45664566+ local version = "1.2.1"
45674567+ local function luajit_vm_3f()
45684568+ 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"))
45694569+ end
45704570+ local function luajit_vm_version()
45714571+ local jit_os
45724572+ if (_G.jit.os == "OSX") then
45734573+ jit_os = "macOS"
45744574+ else
45754575+ jit_os = _G.jit.os
45764576+ end
45774577+ return (_G.jit.version .. " " .. jit_os .. "/" .. _G.jit.arch)
45784578+ end
45794579+ local function fengari_vm_3f()
45804580+ return ((nil ~= _G.fengari) and (type(_G.fengari) == "table") and (nil ~= _G.fengari.VERSION) and (type(_G.fengari.VERSION_NUM) == "number"))
45814581+ end
45824582+ local function fengari_vm_version()
45834583+ return (_G.fengari.RELEASE .. " (" .. _VERSION .. ")")
45844584+ end
45854585+ local function lua_vm_version()
45864586+ if luajit_vm_3f() then
45874587+ return luajit_vm_version()
45884588+ elseif fengari_vm_3f() then
45894589+ return fengari_vm_version()
45904590+ else
45914591+ return ("PUC " .. _VERSION)
45924592+ end
45934593+ end
45944594+ local function runtime_version()
45954595+ return ("Fennel " .. version .. " on " .. lua_vm_version())
45964596+ end
45974597+ local function warn(message)
45984598+ if (_G.io and _G.io.stderr) then
45994599+ return (_G.io.stderr):write(("--WARNING: %s\n"):format(tostring(message)))
46004600+ else
46014601+ return nil
46024602+ end
46034603+ end
46044604+ local len
46054605+ do
46064606+ local _102_, _103_ = pcall(require, "utf8")
46074607+ if ((_102_ == true) and (nil ~= _103_)) then
46084608+ local utf8 = _103_
46094609+ len = utf8.len
46104610+ elseif true then
46114611+ local _ = _102_
46124612+ len = string.len
46134613+ else
46144614+ len = nil
46154615+ end
46164616+ end
46174617+ local function mt_keys_in_order(t, out, used_keys)
46184618+ for _, k in ipairs(getmetatable(t).keys) do
46194619+ if (t[k] and not used_keys[k]) then
46204620+ used_keys[k] = true
46214621+ table.insert(out, k)
46224622+ else
46234623+ end
46244624+ end
31854625 for k in pairs(t) do
31863186- table.insert(keys, k)
46264626+ if not used_keys[k] then
46274627+ table.insert(out, k)
46284628+ else
46294629+ end
31874630 end
31883188- local function _0_(a, b)
31893189- return (tostring(a) < tostring(b))
46314631+ return out
46324632+ end
46334633+ local function stablepairs(t)
46344634+ local keys
46354635+ local _108_
46364636+ do
46374637+ local t_107_ = getmetatable(t)
46384638+ if (nil ~= t_107_) then
46394639+ t_107_ = (t_107_).keys
46404640+ else
46414641+ end
46424642+ _108_ = t_107_
46434643+ end
46444644+ if _108_ then
46454645+ keys = mt_keys_in_order(t, {}, {})
46464646+ else
46474647+ local _110_
46484648+ do
46494649+ local tbl_14_auto = {}
46504650+ local i_15_auto = #tbl_14_auto
46514651+ for k in pairs(t) do
46524652+ local val_16_auto = k
46534653+ if (nil ~= val_16_auto) then
46544654+ i_15_auto = (i_15_auto + 1)
46554655+ do end (tbl_14_auto)[i_15_auto] = val_16_auto
46564656+ else
46574657+ end
46584658+ end
46594659+ _110_ = tbl_14_auto
46604660+ end
46614661+ local function _112_(_241, _242)
46624662+ return (tostring(_241) < tostring(_242))
46634663+ end
46644664+ table.sort(_110_, _112_)
46654665+ keys = _110_
31904666 end
31913191- table.sort(keys, _0_)
31923192- for i, k in ipairs(keys) do
31933193- succ[k] = keys[(i + 1)]
46674667+ local succ
46684668+ do
46694669+ local tbl_11_auto = {}
46704670+ for i, k in ipairs(keys) do
46714671+ local _114_, _115_ = k, keys[(i + 1)]
46724672+ if ((nil ~= _114_) and (nil ~= _115_)) then
46734673+ local k_12_auto = _114_
46744674+ local v_13_auto = _115_
46754675+ tbl_11_auto[k_12_auto] = v_13_auto
46764676+ else
46774677+ end
46784678+ end
46794679+ succ = tbl_11_auto
31944680 end
31953195- local function stablenext(tbl, idx)
31963196- if (idx == nil) then
31973197- return keys[1], tbl[keys[1]]
46814681+ local function stablenext(tbl, key)
46824682+ local next_key
46834683+ if (key == nil) then
46844684+ next_key = keys[1]
31984685 else
31993199- return succ[idx], tbl[succ[idx]]
46864686+ next_key = succ[key]
32004687 end
46884688+ return next_key, tbl[next_key]
32014689 end
32024690 return stablenext, t, nil
32034691 end
32043204- local function map(t, f, out)
32053205- local out0 = (out or {})
32063206- local f0 = nil
46924692+ local function get_in(tbl, path, _3ffallback)
46934693+ assert(("table" == type(tbl)), "get-in expects path to be a table")
46944694+ if (0 == #path) then
46954695+ return _3ffallback
46964696+ else
46974697+ local _118_
46984698+ do
46994699+ local t = tbl
47004700+ for _, k in ipairs(path) do
47014701+ if (nil == t) then break end
47024702+ local _119_ = type(t)
47034703+ if (_119_ == "table") then
47044704+ t = t[k]
47054705+ else
47064706+ t = nil
47074707+ end
47084708+ end
47094709+ _118_ = t
47104710+ end
47114711+ if (nil ~= _118_) then
47124712+ local res = _118_
47134713+ return res
47144714+ elseif true then
47154715+ local _ = _118_
47164716+ return _3ffallback
47174717+ else
47184718+ return nil
47194719+ end
47204720+ end
47214721+ end
47224722+ local function map(t, f, _3fout)
47234723+ local out = (_3fout or {})
47244724+ local f0
32074725 if (type(f) == "function") then
32084726 f0 = f
32094727 else
32103210- local s = f
32113211- local function _0_(x)
32123212- return x[s]
47284728+ local function _123_(_241)
47294729+ return (_241)[f]
32134730 end
32143214- f0 = _0_
47314731+ f0 = _123_
32154732 end
32164733 for _, x in ipairs(t) do
32173217- local _1_0 = f0(x)
32183218- if (nil ~= _1_0) then
32193219- local v = _1_0
32203220- table.insert(out0, v)
47344734+ local _125_ = f0(x)
47354735+ if (nil ~= _125_) then
47364736+ local v = _125_
47374737+ table.insert(out, v)
47384738+ else
32214739 end
32224740 end
32233223- return out0
47414741+ return out
32244742 end
32253225- local function kvmap(t, f, out)
32263226- local out0 = (out or {})
32273227- local f0 = nil
47434743+ local function kvmap(t, f, _3fout)
47444744+ local out = (_3fout or {})
47454745+ local f0
32284746 if (type(f) == "function") then
32294747 f0 = f
32304748 else
32313231- local s = f
32323232- local function _0_(x)
32333233- return x[s]
47494749+ local function _127_(_241)
47504750+ return (_241)[f]
32344751 end
32353235- f0 = _0_
47524752+ f0 = _127_
32364753 end
32374754 for k, x in stablepairs(t) do
32383238- local _1_0, _2_0 = f0(k, x)
32393239- if ((nil ~= _1_0) and (nil ~= _2_0)) then
32403240- local key = _1_0
32413241- local value = _2_0
32423242- out0[key] = value
32433243- elseif (nil ~= _1_0) then
32443244- local value = _1_0
32453245- table.insert(out0, value)
47554755+ local _129_, _130_ = f0(k, x)
47564756+ if ((nil ~= _129_) and (nil ~= _130_)) then
47574757+ local key = _129_
47584758+ local value = _130_
47594759+ out[key] = value
47604760+ elseif (nil ~= _129_) then
47614761+ local value = _129_
47624762+ table.insert(out, value)
47634763+ else
32464764 end
32474765 end
32483248- return out0
47664766+ return out
32494767 end
32503250- local function copy(from, to)
32513251- local to0 = (to or {})
47684768+ local function copy(from, _3fto)
47694769+ local tbl_11_auto = (_3fto or {})
32524770 for k, v in pairs((from or {})) do
32533253- to0[k] = v
47714771+ local _132_, _133_ = k, v
47724772+ if ((nil ~= _132_) and (nil ~= _133_)) then
47734773+ local k_12_auto = _132_
47744774+ local v_13_auto = _133_
47754775+ tbl_11_auto[k_12_auto] = v_13_auto
47764776+ else
47774777+ end
32544778 end
32553255- return to0
47794779+ return tbl_11_auto
32564780 end
32573257- local function member_3f(x, tbl, n)
32583258- local _0_0 = tbl[(n or 1)]
32593259- if (_0_0 == x) then
47814781+ local function member_3f(x, tbl, _3fn)
47824782+ local _135_ = tbl[(_3fn or 1)]
47834783+ if (_135_ == x) then
32604784 return true
32613261- elseif (_0_0 == nil) then
32623262- return false
47854785+ elseif (_135_ == nil) then
47864786+ return nil
47874787+ elseif true then
47884788+ local _ = _135_
47894789+ return member_3f(x, tbl, ((_3fn or 1) + 1))
32634790 else
32643264- local _ = _0_0
32653265- return member_3f(x, tbl, ((n or 1) + 1))
47914791+ return nil
32664792 end
32674793 end
32684794 local function allpairs(tbl)
···32774803 seen[next_state] = true
32784804 return next_state, value
32794805 else
32803280- local meta = getmetatable(t)
32813281- if (meta and meta.__index) then
32823282- t = meta.__index
32833283- return allpairs_next(t)
48064806+ local _137_ = getmetatable(t)
48074807+ if ((_G.type(_137_) == "table") and true) then
48084808+ local __index = (_137_).__index
48094809+ if ("table" == type(__index)) then
48104810+ t = __index
48114811+ return allpairs_next(t)
48124812+ else
48134813+ return nil
48144814+ end
48154815+ else
48164816+ return nil
32844817 end
32854818 end
32864819 end
···32904823 return self[1]
32914824 end
32924825 local nil_sym = nil
32933293- local function list__3estring(self, tostring2)
32943294- local safe, max = {}, 0
48264826+ local function list__3estring(self, _3ftostring2)
48274827+ local safe = {}
48284828+ local max = 0
32954829 for k in pairs(self) do
32963296- if ((type(k) == "number") and (k > max)) then
48304830+ if ((type(k) == "number") and (max < k)) then
32974831 max = k
48324832+ else
32984833 end
32994834 end
33004835 for i = 1, max do
33014836 safe[i] = (((self[i] == nil) and nil_sym) or self[i])
33024837 end
33033303- return ("(" .. table.concat(map(safe, (tostring2 or tostring)), " ", 1, max) .. ")")
48384838+ return ("(" .. table.concat(map(safe, (_3ftostring2 or view)), " ", 1, max) .. ")")
33044839 end
33053305- local symbol_mt = {"SYMBOL", __fennelview = deref, __tostring = deref}
33063306- local expr_mt = {"EXPR", __tostring = deref}
33073307- local list_mt = {"LIST", __fennelview = list__3estring, __tostring = list__3estring}
33083308- local comment_mt = {"COMMENT", __fennelview = deref, __tostring = deref}
48404840+ local function comment_view(c)
48414841+ return c, true
48424842+ end
48434843+ local function sym_3d(a, b)
48444844+ return ((deref(a) == deref(b)) and (getmetatable(a) == getmetatable(b)))
48454845+ end
48464846+ local function sym_3c(a, b)
48474847+ return (a[1] < tostring(b))
48484848+ end
48494849+ local symbol_mt = {__fennelview = deref, __tostring = deref, __eq = sym_3d, __lt = sym_3c, "SYMBOL"}
48504850+ local expr_mt
48514851+ local function _142_(x)
48524852+ return tostring(deref(x))
48534853+ end
48544854+ expr_mt = {__tostring = _142_, "EXPR"}
48554855+ local list_mt = {__fennelview = list__3estring, __tostring = list__3estring, "LIST"}
48564856+ local comment_mt = {__fennelview = comment_view, __tostring = deref, __eq = sym_3d, __lt = sym_3c, "COMMENT"}
33094857 local sequence_marker = {"SEQUENCE"}
33103310- local vararg = setmetatable({"..."}, {"VARARG", __fennelview = deref, __tostring = deref})
33113311- local getenv = nil
33123312- local function _0_()
48584858+ local varg_mt = {__fennelview = deref, __tostring = deref, "VARARG"}
48594859+ local getenv
48604860+ local function _143_()
33134861 return nil
33144862 end
33153315- getenv = ((os and os.getenv) or _0_)
48634863+ getenv = ((os and os.getenv) or _143_)
33164864 local function debug_on_3f(flag)
33174865 local level = (getenv("FENNEL_DEBUG") or "")
33184866 return ((level == "all") or level:find(flag))
···33204868 local function list(...)
33214869 return setmetatable({...}, list_mt)
33224870 end
33233323- local function sym(str, scope, source)
33243324- local s = {str, scope = scope}
33253325- for k, v in pairs((source or {})) do
33263326- if (type(k) == "string") then
33273327- s[k] = v
48714871+ local function sym(str, _3fsource)
48724872+ local _144_
48734873+ do
48744874+ local tbl_11_auto = {str}
48754875+ for k, v in pairs((_3fsource or {})) do
48764876+ local _145_, _146_ = nil, nil
48774877+ if (type(k) == "string") then
48784878+ _145_, _146_ = k, v
48794879+ else
48804880+ _145_, _146_ = nil
48814881+ end
48824882+ if ((nil ~= _145_) and (nil ~= _146_)) then
48834883+ local k_12_auto = _145_
48844884+ local v_13_auto = _146_
48854885+ tbl_11_auto[k_12_auto] = v_13_auto
48864886+ else
48874887+ end
33284888 end
48894889+ _144_ = tbl_11_auto
33294890 end
33303330- return setmetatable(s, symbol_mt)
48914891+ return setmetatable(_144_, symbol_mt)
33314892 end
33324893 nil_sym = sym("nil")
33334894 local function sequence(...)
33344895 return setmetatable({...}, {sequence = sequence_marker})
33354896 end
33364897 local function expr(strcode, etype)
33373337- return setmetatable({strcode, type = etype}, expr_mt)
48984898+ return setmetatable({type = etype, strcode}, expr_mt)
33384899 end
33393339- local function comment_2a(contents)
33403340- return setmetatable({contents}, comment_mt)
49004900+ local function comment_2a(contents, _3fsource)
49014901+ local _let_149_ = (_3fsource or {})
49024902+ local filename = _let_149_["filename"]
49034903+ local line = _let_149_["line"]
49044904+ return setmetatable({filename = filename, line = line, contents}, comment_mt)
33414905 end
33423342- local function varg()
33433343- return vararg
49064906+ local function varg(_3fsource)
49074907+ local _150_
49084908+ do
49094909+ local tbl_11_auto = {"..."}
49104910+ for k, v in pairs((_3fsource or {})) do
49114911+ local _151_, _152_ = nil, nil
49124912+ if (type(k) == "string") then
49134913+ _151_, _152_ = k, v
49144914+ else
49154915+ _151_, _152_ = nil
49164916+ end
49174917+ if ((nil ~= _151_) and (nil ~= _152_)) then
49184918+ local k_12_auto = _151_
49194919+ local v_13_auto = _152_
49204920+ tbl_11_auto[k_12_auto] = v_13_auto
49214921+ else
49224922+ end
49234923+ end
49244924+ _150_ = tbl_11_auto
49254925+ end
49264926+ return setmetatable(_150_, varg_mt)
33444927 end
33454928 local function expr_3f(x)
33464929 return ((type(x) == "table") and (getmetatable(x) == expr_mt) and x)
33474930 end
33484931 local function varg_3f(x)
33493349- return ((x == vararg) and x)
49324932+ return ((type(x) == "table") and (getmetatable(x) == varg_mt) and x)
33504933 end
33514934 local function list_3f(x)
33524935 return ((type(x) == "table") and (getmetatable(x) == list_mt) and x)
···33544937 local function sym_3f(x)
33554938 return ((type(x) == "table") and (getmetatable(x) == symbol_mt) and x)
33564939 end
33573357- local function table_3f(x)
33583358- return ((type(x) == "table") and (x ~= vararg) and (getmetatable(x) ~= list_mt) and (getmetatable(x) ~= symbol_mt) and x)
33593359- end
33604940 local function sequence_3f(x)
33614941 local mt = ((type(x) == "table") and getmetatable(x))
33624942 return (mt and (mt.sequence == sequence_marker) and x)
···33644944 local function comment_3f(x)
33654945 return ((type(x) == "table") and (getmetatable(x) == comment_mt) and x)
33664946 end
49474947+ local function table_3f(x)
49484948+ return ((type(x) == "table") and not varg_3f(x) and (getmetatable(x) ~= list_mt) and (getmetatable(x) ~= symbol_mt) and not comment_3f(x) and x)
49494949+ end
49504950+ local function string_3f(x)
49514951+ return (type(x) == "string")
49524952+ end
33674953 local function multi_sym_3f(str)
33684954 if sym_3f(str) then
33694955 return multi_sym_3f(tostring(str))
···33754961 local last_char = part:sub(( - 1))
33764962 if (last_char == ":") then
33774963 parts["multi-sym-method-call"] = true
49644964+ else
33784965 end
33794966 if ((last_char == ":") or (last_char == ".")) then
33804967 parts[(#parts + 1)] = part:sub(1, ( - 2))
···33824969 parts[(#parts + 1)] = part
33834970 end
33844971 end
33853385- return ((#parts > 0) and (str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte(( - 1)) ~= string.byte(".")) and parts)
49724972+ return ((0 < #parts) and (str:match("%.") or str:match(":")) and not str:match("%.%.") and (str:byte() ~= string.byte(".")) and (str:byte(( - 1)) ~= string.byte(".")) and parts)
33864973 end
33874974 end
33884975 local function quoted_3f(symbol)
33894976 return symbol.quoted
33904977 end
33913391- local function walk_tree(root, f, custom_iterator)
49784978+ local function ast_source(ast)
49794979+ if (table_3f(ast) or sequence_3f(ast)) then
49804980+ return (getmetatable(ast) or {})
49814981+ elseif ("table" == type(ast)) then
49824982+ return ast
49834983+ else
49844984+ return {}
49854985+ end
49864986+ end
49874987+ local function walk_tree(root, f, _3fcustom_iterator)
33924988 local function walk(iterfn, parent, idx, node)
33934989 if f(idx, node, parent) then
33944990 for k, v in iterfn(node) do
33954991 walk(iterfn, node, k, v)
33964992 end
33974993 return nil
49944994+ else
49954995+ return nil
33984996 end
33994997 end
34003400- walk((custom_iterator or pairs), nil, nil, root)
49984998+ walk((_3fcustom_iterator or pairs), nil, nil, root)
34014999 return root
34025000 end
34035001 local lua_keywords = {"and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", "goto"}
···34145012 end
34155013 return subopts
34165014 end
34173417- local root = nil
34183418- local function _1_()
50155015+ local root
50165016+ local function _160_()
34195017 end
34203420- root = {chunk = nil, options = nil, reset = _1_, scope = nil}
34213421- root["set-reset"] = function(_2_0)
34223422- local _3_ = _2_0
34233423- local chunk = _3_["chunk"]
34243424- local options = _3_["options"]
34253425- local reset = _3_["reset"]
34263426- local scope = _3_["scope"]
50185018+ root = {chunk = nil, scope = nil, options = nil, reset = _160_}
50195019+ root["set-reset"] = function(_161_)
50205020+ local _arg_162_ = _161_
50215021+ local chunk = _arg_162_["chunk"]
50225022+ local scope = _arg_162_["scope"]
50235023+ local options = _arg_162_["options"]
50245024+ local reset = _arg_162_["reset"]
34275025 root.reset = function()
34285026 root.chunk, root.scope, root.options, root.reset = chunk, scope, options, reset
34295027 return nil
34305028 end
34315029 return root.reset
34325030 end
34333433- local function hook(event, ...)
34343434- if (root.options and root.options.plugins) then
34353435- for _, plugin in ipairs(root.options.plugins) do
34363436- local _3_0 = plugin[event]
34373437- if (nil ~= _3_0) then
34383438- local f = _3_0
34393439- f(...)
50315031+ local warned = {}
50325032+ local function check_plugin_version(_163_)
50335033+ local _arg_164_ = _163_
50345034+ local name = _arg_164_["name"]
50355035+ local versions = _arg_164_["versions"]
50365036+ local plugin = _arg_164_
50375037+ if (not member_3f(version:gsub("-dev", ""), (versions or {})) and not warned[plugin]) then
50385038+ warned[plugin] = true
50395039+ return warn(string.format("plugin %s does not support Fennel version %s", (name or "unknown"), version))
50405040+ else
50415041+ return nil
50425042+ end
50435043+ end
50445044+ local function hook_opts(event, _3foptions, ...)
50455045+ local plugins
50465046+ local function _167_(...)
50475047+ local t_166_ = _3foptions
50485048+ if (nil ~= t_166_) then
50495049+ t_166_ = (t_166_).plugins
50505050+ else
50515051+ end
50525052+ return t_166_
50535053+ end
50545054+ local function _170_(...)
50555055+ local t_169_ = root.options
50565056+ if (nil ~= t_169_) then
50575057+ t_169_ = (t_169_).plugins
50585058+ else
50595059+ end
50605060+ return t_169_
50615061+ end
50625062+ plugins = (_167_(...) or _170_(...))
50635063+ if plugins then
50645064+ local result = nil
50655065+ for _, plugin in ipairs(plugins) do
50665066+ if result then break end
50675067+ check_plugin_version(plugin)
50685068+ local _172_ = plugin[event]
50695069+ if (nil ~= _172_) then
50705070+ local f = _172_
50715071+ result = f(...)
50725072+ else
50735073+ result = nil
34405074 end
34415075 end
50765076+ return result
50775077+ else
34425078 return nil
34435079 end
34445080 end
34453445- return {["comment?"] = comment_3f, ["debug-on?"] = debug_on_3f, ["expr?"] = expr_3f, ["list?"] = list_3f, ["lua-keywords"] = lua_keywords, ["member?"] = member_3f, ["multi-sym?"] = multi_sym_3f, ["propagate-options"] = propagate_options, ["quoted?"] = quoted_3f, ["sequence?"] = sequence_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, deref = deref, expr = expr, hook = hook, kvmap = kvmap, list = list, map = map, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), root = root, sequence = sequence, stablepairs = stablepairs, sym = sym, varg = varg}
50815081+ local function hook(event, ...)
50825082+ return hook_opts(event, root.options, ...)
50835083+ end
50845084+ return {warn = warn, allpairs = allpairs, stablepairs = stablepairs, copy = copy, ["get-in"] = get_in, kvmap = kvmap, map = map, ["walk-tree"] = walk_tree, ["member?"] = member_3f, list = list, sequence = sequence, sym = sym, varg = varg, expr = expr, comment = comment_2a, ["comment?"] = comment_3f, ["expr?"] = expr_3f, ["list?"] = list_3f, ["multi-sym?"] = multi_sym_3f, ["sequence?"] = sequence_3f, ["sym?"] = sym_3f, ["table?"] = table_3f, ["varg?"] = varg_3f, ["quoted?"] = quoted_3f, ["string?"] = string_3f, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["lua-keywords"] = lua_keywords, hook = hook, ["hook-opts"] = hook_opts, ["propagate-options"] = propagate_options, root = root, ["debug-on?"] = debug_on_3f, ["ast-source"] = ast_source, version = version, ["runtime-version"] = runtime_version, len = len, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";")}
34465085end
34475086utils = require("fennel.utils")
34485087local parser = require("fennel.parser")
···34505089local specials = require("fennel.specials")
34515090local repl = require("fennel.repl")
34525091local view = require("fennel.view")
34533453-local function get_env(env)
50925092+local function eval_env(env, opts)
34545093 if (env == "_COMPILER") then
34553455- local env0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {})
34563456- local mt = getmetatable(env0)
34573457- mt.__index = _G
50945094+ local env0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}, opts)
50955095+ if (opts.allowedGlobals == nil) then
50965096+ opts.allowedGlobals = specials["current-global-names"](env0)
50975097+ else
50985098+ end
34585099 return specials["wrap-env"](env0)
34595100 else
34605101 return (env and specials["wrap-env"](env))
34615102 end
34625103end
34633463-local function eval(str, options, ...)
51045104+local function eval_opts(options, str)
34645105 local opts = utils.copy(options)
34653465- local _ = nil
34663466- if ((opts.allowedGlobals == nil) and not getmetatable(opts.env)) then
51065106+ if (opts.allowedGlobals == nil) then
34675107 opts.allowedGlobals = specials["current-global-names"](opts.env)
34683468- _ = nil
34695108 else
34703470- _ = nil
34715109 end
34723472- local env = get_env(opts.env)
51105110+ if (not opts.filename and not opts.source) then
51115111+ opts.source = str
51125112+ else
51135113+ end
51145114+ if (opts.env == "_COMPILER") then
51155115+ opts.scope = compiler["make-scope"](compiler.scopes.compiler)
51165116+ else
51175117+ end
51185118+ return opts
51195119+end
51205120+local function eval(str, options, ...)
51215121+ local opts = eval_opts(options, str)
51225122+ local env = eval_env(opts.env, opts)
34735123 local lua_source = compiler["compile-string"](str, opts)
34743474- local loader = nil
34753475- local function _1_(...)
51245124+ local loader
51255125+ local function _735_(...)
34765126 if opts.filename then
34775127 return ("@" .. opts.filename)
34785128 else
34795129 return str
34805130 end
34815131 end
34823482- loader = specials["load-code"](lua_source, env, _1_(...))
51325132+ loader = specials["load-code"](lua_source, env, _735_(...))
34835133 opts.filename = nil
34845134 return loader(...)
34855135end
···34915141 opts.filename = filename
34925142 return eval(source, opts, ...)
34935143end
34943494-local mod = {["compile-stream"] = compiler["compile-stream"], ["compile-string"] = compiler["compile-string"], ["list?"] = utils["list?"], ["load-code"] = specials["load-code"], ["macro-loaded"] = specials["macro-loaded"], ["make-searcher"] = specials["make-searcher"], ["search-module"] = specials["search-module"], ["sequence?"] = utils["sequence?"], ["string-stream"] = parser["string-stream"], ["sym-char?"] = parser["sym-char?"], ["sym?"] = utils["sym?"], compile = compiler.compile, compile1 = compiler.compile1, compileStream = compiler["compile-stream"], compileString = compiler["compile-string"], doc = specials.doc, dofile = dofile_2a, eval = eval, gensym = compiler.gensym, granulate = parser.granulate, list = utils.list, loadCode = specials["load-code"], macroLoaded = specials["macro-loaded"], makeSearcher = specials["make-searcher"], make_searcher = specials["make-searcher"], mangle = compiler["global-mangling"], metadata = compiler.metadata, parser = parser.parser, path = utils.path, repl = repl, scope = compiler["make-scope"], searchModule = specials["search-module"], searcher = specials["make-searcher"](), sequence = utils.sequence, stringStream = parser["string-stream"], sym = utils.sym, traceback = compiler.traceback, unmangle = compiler["global-unmangling"], varg = utils.varg, version = "0.8.0", view = view}
51445144+local function syntax()
51455145+ local body_3f = {"when", "with-open", "collect", "icollect", "fcollect", "lambda", "\206\187", "macro", "match", "match-try", "accumulate", "doto"}
51465146+ local binding_3f = {"collect", "icollect", "fcollect", "each", "for", "let", "with-open", "accumulate"}
51475147+ local define_3f = {"fn", "lambda", "\206\187", "var", "local", "macro", "macros", "global"}
51485148+ local out = {}
51495149+ for k, v in pairs(compiler.scopes.global.specials) do
51505150+ local metadata = (compiler.metadata[v] or {})
51515151+ do end (out)[k] = {["special?"] = true, ["body-form?"] = metadata["fnl/body-form?"], ["binding-form?"] = utils["member?"](k, binding_3f), ["define?"] = utils["member?"](k, define_3f)}
51525152+ end
51535153+ for k, v in pairs(compiler.scopes.global.macros) do
51545154+ out[k] = {["macro?"] = true, ["body-form?"] = utils["member?"](k, body_3f), ["binding-form?"] = utils["member?"](k, binding_3f), ["define?"] = utils["member?"](k, define_3f)}
51555155+ end
51565156+ for k, v in pairs(_G) do
51575157+ local _736_ = type(v)
51585158+ if (_736_ == "function") then
51595159+ out[k] = {["global?"] = true, ["function?"] = true}
51605160+ elseif (_736_ == "table") then
51615161+ for k2, v2 in pairs(v) do
51625162+ if (("function" == type(v2)) and (k ~= "_G")) then
51635163+ out[(k .. "." .. k2)] = {["function?"] = true, ["global?"] = true}
51645164+ else
51655165+ end
51665166+ end
51675167+ out[k] = {["global?"] = true}
51685168+ else
51695169+ end
51705170+ end
51715171+ return out
51725172+end
51735173+local mod = {list = utils.list, ["list?"] = utils["list?"], sym = utils.sym, ["sym?"] = utils["sym?"], ["multi-sym?"] = utils["multi-sym?"], sequence = utils.sequence, ["sequence?"] = utils["sequence?"], ["table?"] = utils["table?"], comment = utils.comment, ["comment?"] = utils["comment?"], varg = utils.varg, ["varg?"] = utils["varg?"], ["sym-char?"] = parser["sym-char?"], parser = parser.parser, compile = compiler.compile, ["compile-string"] = compiler["compile-string"], ["compile-stream"] = compiler["compile-stream"], eval = eval, repl = repl, view = view, dofile = dofile_2a, ["load-code"] = specials["load-code"], doc = specials.doc, metadata = compiler.metadata, traceback = compiler.traceback, version = utils.version, ["runtime-version"] = utils["runtime-version"], ["ast-source"] = utils["ast-source"], path = utils.path, ["macro-path"] = utils["macro-path"], ["macro-loaded"] = specials["macro-loaded"], ["macro-searchers"] = specials["macro-searchers"], ["search-module"] = specials["search-module"], ["make-searcher"] = specials["make-searcher"], searcher = specials["make-searcher"](), syntax = syntax, gensym = compiler.gensym, scope = compiler["make-scope"], mangle = compiler["global-mangling"], unmangle = compiler["global-unmangling"], compile1 = compiler.compile1, ["string-stream"] = parser["string-stream"], granulate = parser.granulate, loadCode = specials["load-code"], make_searcher = specials["make-searcher"], makeSearcher = specials["make-searcher"], searchModule = specials["search-module"], macroPath = utils["macro-path"], macroSearchers = specials["macro-searchers"], macroLoaded = specials["macro-loaded"], compileStream = compiler["compile-stream"], compileString = compiler["compile-string"], stringStream = parser["string-stream"], runtimeVersion = utils["runtime-version"]}
51745174+mod.install = function(_3fopts)
51755175+ table.insert((package.searchers or package.loaders), specials["make-searcher"](_3fopts))
51765176+ return mod
51775177+end
34955178utils["fennel-module"] = mod
34965179do
34973497- local builtin_macros = [===[;; This module contains all the built-in Fennel macros. Unlike all the other
34983498- ;; modules that are loaded by the old bootstrap compiler, this runs in the
34993499- ;; compiler scope of the version of the compiler being defined.
51805180+ local builtin_macros = [===[;; These macros are awkward because their definition cannot rely on the any
51815181+ ;; built-in macros, only special forms. (no when, no icollect, etc)
3500518235013501- ;; The code for these macros is somewhat idiosyncratic because it cannot use any
35023502- ;; macros which have not yet been defined.
35033503-35043504- ;; TODO: some of these macros modify their arguments; we should stop doing that,
35053505- ;; but in a way that preserves file/line metadata.
51835183+ (fn copy [t]
51845184+ (let [out []]
51855185+ (each [_ v (ipairs t)] (table.insert out v))
51865186+ (setmetatable out (getmetatable t))))
3506518735073507- (fn -> [val ...]
51885188+ (fn ->* [val ...]
35085189 "Thread-first macro.
35095190 Take the first value and splice it into the second form as its first argument.
35105191 The value of the second form is spliced into the first arg of the third, etc."
35115192 (var x val)
35125193 (each [_ e (ipairs [...])]
35133513- (let [elt (if (list? e) e (list e))]
51945194+ (let [elt (if (list? e) (copy e) (list e))]
35145195 (table.insert elt 2 x)
35155196 (set x elt)))
35165197 x)
3517519835183518- (fn ->> [val ...]
51995199+ (fn ->>* [val ...]
35195200 "Thread-last macro.
35205201 Same as ->, except splices the value into the last position of each form
35215202 rather than the first."
35225203 (var x val)
35233523- (each [_ e (pairs [...])]
35243524- (let [elt (if (list? e) e (list e))]
52045204+ (each [_ e (ipairs [...])]
52055205+ (let [elt (if (list? e) (copy e) (list e))]
35255206 (table.insert elt x)
35265207 (set x elt)))
35275208 x)
3528520935293529- (fn -?> [val ...]
52105210+ (fn -?>* [val ?e ...]
35305211 "Nil-safe thread-first macro.
35315212 Same as -> except will short-circuit with nil when it encounters a nil value."
35323532- (if (= 0 (select "#" ...))
52135213+ (if (= nil ?e)
35335214 val
35343534- (let [els [...]
35353535- e (table.remove els 1)
35363536- el (if (list? e) e (list e))
52155215+ (let [el (if (list? ?e) (copy ?e) (list ?e))
35375216 tmp (gensym)]
35385217 (table.insert el 2 tmp)
35395218 `(let [,tmp ,val]
35403540- (if ,tmp
35413541- (-?> ,el ,(unpack els))
52195219+ (if (not= nil ,tmp)
52205220+ (-?> ,el ,...)
35425221 ,tmp)))))
3543522235443544- (fn -?>> [val ...]
52235223+ (fn -?>>* [val ?e ...]
35455224 "Nil-safe thread-last macro.
35465225 Same as ->> except will short-circuit with nil when it encounters a nil value."
35473547- (if (= 0 (select "#" ...))
52265226+ (if (= nil ?e)
35485227 val
35493549- (let [els [...]
35503550- e (table.remove els 1)
35513551- el (if (list? e) e (list e))
52285228+ (let [el (if (list? ?e) (copy ?e) (list ?e))
35525229 tmp (gensym)]
35535230 (table.insert el tmp)
35545231 `(let [,tmp ,val]
35553555- (if ,tmp
35563556- (-?>> ,el ,(unpack els))
52325232+ (if (not= ,tmp nil)
52335233+ (-?>> ,el ,...)
35575234 ,tmp)))))
3558523535593559- (fn doto [val ...]
35603560- "Evaluates val and splices it into the first argument of subsequent forms."
35613561- (let [name (gensym)
35623562- form `(let [,name ,val])]
35633563- (each [_ elt (pairs [...])]
35643564- (table.insert elt 2 name)
35653565- (table.insert form elt))
52365236+ (fn ?dot [tbl ...]
52375237+ "Nil-safe table look up.
52385238+ Same as . (dot), except will short-circuit with nil when it encounters
52395239+ a nil value in any of subsequent keys."
52405240+ (let [head (gensym :t)
52415241+ lookups `(do
52425242+ (var ,head ,tbl)
52435243+ ,head)]
52445244+ (each [_ k (ipairs [...])]
52455245+ ;; Kinda gnarly to reassign in place like this, but it emits the best lua.
52465246+ ;; With this impl, it emits a flat, concise, and readable set of ifs
52475247+ (table.insert lookups (# lookups) `(if (not= nil ,head)
52485248+ (set ,head (. ,head ,k)))))
52495249+ lookups))
52505250+52515251+ (fn doto* [val ...]
52525252+ "Evaluate val and splice it into the first argument of subsequent forms."
52535253+ (assert (not= val nil) "missing subject")
52545254+ (let [rebind? (or (not (sym? val))
52555255+ (multi-sym? val))
52565256+ name (if rebind? (gensym) val)
52575257+ form (if rebind? `(let [,name ,val]) `(do))]
52585258+ (each [_ elt (ipairs [...])]
52595259+ (let [elt (if (list? elt) (copy elt) (list elt))]
52605260+ (table.insert elt 2 name)
52615261+ (table.insert form elt)))
35665262 (table.insert form name)
35675263 form))
3568526435693569- (fn when [condition body1 ...]
52655265+ (fn when* [condition body1 ...]
35705266 "Evaluate body for side-effects only when condition is truthy."
35715267 (assert body1 "expected body")
35725268 `(if ,condition
35733573- (do ,body1 ,...)))
52695269+ (do
52705270+ ,body1
52715271+ ,...)))
3574527235753575- (fn with-open [closable-bindings ...]
52735273+ (fn with-open* [closable-bindings ...]
35765274 "Like `let`, but invokes (v:close) on each binding after evaluating the body.
35775275 The body is evaluated inside `xpcall` so that bound values will be closed upon
35785276 encountering an error before propagating it."
35793579- (let [bodyfn `(fn [] ,...)
35803580- closer `(fn close-handlers# [ok# ...] (if ok# ...
35813581- (error ... 0)))
52775277+ (let [bodyfn `(fn []
52785278+ ,...)
52795279+ closer `(fn close-handlers# [ok# ...]
52805280+ (if ok# ... (error ... 0)))
35825281 traceback `(. (or package.loaded.fennel debug) :traceback)]
35833583- (for [i 1 (# closable-bindings) 2]
52825282+ (for [i 1 (length closable-bindings) 2]
35845283 (assert (sym? (. closable-bindings i))
35855284 "with-open only allows symbols in bindings")
35865285 (table.insert closer 4 `(: ,(. closable-bindings i) :close)))
35873587- `(let ,closable-bindings ,closer
35883588- (close-handlers# (xpcall ,bodyfn ,traceback)))))
52865286+ `(let ,closable-bindings
52875287+ ,closer
52885288+ (close-handlers# (_G.xpcall ,bodyfn ,traceback)))))
3589528935903590- (fn collect [iter-tbl key-value-expr ...]
35913591- "Returns a table made by running an iterator and evaluating an expression
35923592- that returns key-value pairs to be inserted sequentially into the table.
35933593- This can be thought of as a \"table comprehension\". The provided key-value
35943594- expression must return either 2 values, or nil.
52905290+ (fn extract-into [iter-tbl]
52915291+ (var (into iter-out found?) (values [] (copy iter-tbl)))
52925292+ (for [i (length iter-tbl) 2 -1]
52935293+ (let [item (. iter-tbl i)]
52945294+ (if (or (= `&into item)
52955295+ (= :into item))
52965296+ (do
52975297+ (assert (not found?) "expected only one &into clause")
52985298+ (set found? true)
52995299+ (set into (. iter-tbl (+ i 1)))
53005300+ (table.remove iter-out i)
53015301+ (table.remove iter-out i)))))
53025302+ (assert (or (not found?) (sym? into) (table? into) (list? into))
53035303+ "expected table, function call, or symbol in &into clause")
53045304+ (values into iter-out))
53055305+53065306+ (fn collect* [iter-tbl key-expr value-expr ...]
53075307+ "Return a table made by running an iterator and evaluating an expression that
53085308+ returns key-value pairs to be inserted sequentially into the table. This can
53095309+ be thought of as a table comprehension. The body should provide two expressions
53105310+ (used as key and value) or nil, which causes it to be omitted.
3595531135965312 For example,
35975313 (collect [k v (pairs {:apple \"red\" :orange \"orange\"})]
35985314 (values v k))
35995315 returns
36003600- {:red \"apple\" :orange \"orange\"}"
36013601- (assert (and (sequence? iter-tbl) (>= (length iter-tbl) 2))
53165316+ {:red \"apple\" :orange \"orange\"}
53175317+53185318+ Supports an &into clause after the iterator to put results in an existing table.
53195319+ Supports early termination with an &until clause."
53205320+ (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl)))
36025321 "expected iterator binding table")
36033603- (assert (not= nil key-value-expr)
36043604- "expected key-value expression")
53225322+ (assert (not= nil key-expr) "expected key and value expression")
53235323+ (assert (= nil ...)
53245324+ "expected 1 or 2 body expressions; wrap multiple expressions with do")
53255325+ (let [kv-expr (if (= nil value-expr) key-expr `(values ,key-expr ,value-expr))
53265326+ (into iter) (extract-into iter-tbl)]
53275327+ `(let [tbl# ,into]
53285328+ (each ,iter
53295329+ (match ,kv-expr
53305330+ (k# v#) (tset tbl# k# v#)))
53315331+ tbl#)))
53325332+53335333+ (fn seq-collect [how iter-tbl value-expr ...]
53345334+ "Common part between icollect and fcollect for producing sequential tables.
53355335+53365336+ Iteration code only deffers in using the for or each keyword, the rest
53375337+ of the generated code is identical."
53385338+ (assert (not= nil value-expr) "expected table value expression")
36055339 (assert (= nil ...)
36063606- "expected exactly one body expression. Wrap multiple expressions with do")
36073607- `(let [tbl# {}]
36083608- (each ,iter-tbl
36093609- (match ,key-value-expr
36103610- (k# v#) (tset tbl# k# v#)))
36113611- tbl#))
53405340+ "expected exactly one body expression. Wrap multiple expressions in do")
53415341+ (let [(into iter) (extract-into iter-tbl)]
53425342+ `(let [tbl# ,into]
53435343+ ;; believe it or not, using a var here has a pretty good performance
53445344+ ;; boost: https://p.hagelb.org/icollect-performance.html
53455345+ (var i# (length tbl#))
53465346+ (,how ,iter
53475347+ (let [val# ,value-expr]
53485348+ (when (not= nil val#)
53495349+ (set i# (+ i# 1))
53505350+ (tset tbl# i# val#))))
53515351+ tbl#)))
3612535236133613- (fn icollect [iter-tbl value-expr ...]
36143614- "Returns a sequential table made by running an iterator and evaluating an
53535353+ (fn icollect* [iter-tbl value-expr ...]
53545354+ "Return a sequential table made by running an iterator and evaluating an
36155355 expression that returns values to be inserted sequentially into the table.
36163616- This can be thought of as a \"list comprehension\".
53565356+ This can be thought of as a table comprehension. If the body evaluates to nil
53575357+ that element is omitted.
3617535836185359 For example,
36193619- (icollect [_ v (ipairs [1 2 3 4 5])] (when (> v 2) (* v v)))
53605360+ (icollect [_ v (ipairs [1 2 3 4 5])]
53615361+ (when (not= v 3)
53625362+ (* v v)))
36205363 returns
36213621- [9 16 25]"
36223622- (assert (and (sequence? iter-tbl) (>= (length iter-tbl) 2))
53645364+ [1 4 16 25]
53655365+53665366+ Supports an &into clause after the iterator to put results in an existing table.
53675367+ Supports early termination with an &until clause."
53685368+ (assert (and (sequence? iter-tbl) (<= 2 (length iter-tbl)))
36235369 "expected iterator binding table")
36243624- (assert (not= nil value-expr)
36253625- "expected table value expression")
53705370+ (seq-collect 'each iter-tbl value-expr ...))
53715371+53725372+ (fn fcollect* [iter-tbl value-expr ...]
53735373+ "Return a sequential table made by advancing a range as specified by
53745374+ for, and evaluating an expression that returns values to be inserted
53755375+ sequentially into the table. This can be thought of as a range
53765376+ comprehension. If the body evaluates to nil that element is omitted.
53775377+53785378+ For example,
53795379+ (fcollect [i 1 10 2]
53805380+ (when (not= i 3)
53815381+ (* i i)))
53825382+ returns
53835383+ [1 25 49 81]
53845384+53855385+ Supports an &into clause after the range to put results in an existing table.
53865386+ Supports early termination with an &until clause."
53875387+ (assert (and (sequence? iter-tbl) (< 2 (length iter-tbl)))
53885388+ "expected range binding table")
53895389+ (seq-collect 'for iter-tbl value-expr ...))
53905390+53915391+ (fn accumulate* [iter-tbl body ...]
53925392+ "Accumulation macro.
53935393+53945394+ It takes a binding table and an expression as its arguments. In the binding
53955395+ table, the first form starts out bound to the second value, which is an initial
53965396+ accumulator. The rest are an iterator binding table in the format `each` takes.
53975397+53985398+ It runs through the iterator in each step of which the given expression is
53995399+ evaluated, and the accumulator is set to the value of the expression. It
54005400+ eventually returns the final value of the accumulator.
54015401+54025402+ For example,
54035403+ (accumulate [total 0
54045404+ _ n (pairs {:apple 2 :orange 3})]
54055405+ (+ total n))
54065406+ returns 5"
54075407+ (assert (and (sequence? iter-tbl) (<= 4 (length iter-tbl)))
54085408+ "expected initial value and iterator binding table")
54095409+ (assert (not= nil body) "expected body expression")
36265410 (assert (= nil ...)
36275411 "expected exactly one body expression. Wrap multiple expressions with do")
36283628- `(let [tbl# []]
36293629- (each ,iter-tbl
36303630- (tset tbl# (+ (length tbl#) 1) ,value-expr))
36313631- tbl#))
54125412+ (let [accum-var (. iter-tbl 1)
54135413+ accum-init (. iter-tbl 2)]
54145414+ `(do
54155415+ (var ,accum-var ,accum-init)
54165416+ (each ,[(unpack iter-tbl 3)]
54175417+ (set ,accum-var ,body))
54185418+ ,(if (list? accum-var)
54195419+ (list (sym :values) (unpack accum-var))
54205420+ accum-var))))
3632542136333633- (fn partial [f ...]
36343634- "Returns a function with all arguments partially applied to f."
36353635- (let [body (list f ...)]
36363636- (table.insert body _VARARG)
36373637- `(fn [,_VARARG] ,body)))
54225422+ (fn double-eval-safe? [x type]
54235423+ (or (= :number type) (= :string type) (= :boolean type)
54245424+ (and (sym? x) (not (multi-sym? x)))))
3638542536393639- (fn pick-args [n f]
36403640- "Creates a function of arity n that applies its arguments to f.
54265426+ (fn partial* [f ...]
54275427+ "Return a function with all arguments partially applied to f."
54285428+ (assert f "expected a function to partially apply")
54295429+ (let [bindings []
54305430+ args []]
54315431+ (each [_ arg (ipairs [...])]
54325432+ (if (double-eval-safe? arg (type arg))
54335433+ (table.insert args arg)
54345434+ (let [name (gensym)]
54355435+ (table.insert bindings name)
54365436+ (table.insert bindings arg)
54375437+ (table.insert args name))))
54385438+ (let [body (list f (unpack args))]
54395439+ (table.insert body _VARARG)
54405440+ ;; only use the extra let if we need double-eval protection
54415441+ (if (= 0 (length bindings))
54425442+ `(fn [,_VARARG] ,body)
54435443+ `(let ,bindings
54445444+ (fn [,_VARARG] ,body))))))
54455445+54465446+ (fn pick-args* [n f]
54475447+ "Create a function of arity n that applies its arguments to f.
3641544836425449 For example,
36435450 (pick-args 2 func)
36445451 expands to
36455452 (fn [_0_ _1_] (func _0_ _1_))"
36463646- (assert (and (= (type n) :number) (= n (math.floor n)) (>= n 0))
36473647- "Expected n to be an integer literal >= 0.")
54535453+ (if (and _G.io _G.io.stderr)
54545454+ (_G.io.stderr:write
54555455+ "-- WARNING: pick-args is deprecated and will be removed in the future.\n"))
54565456+ (assert (and (= (type n) :number) (= n (math.floor n)) (<= 0 n))
54575457+ (.. "Expected n to be an integer literal >= 0, got " (tostring n)))
36485458 (let [bindings []]
36493649- (for [i 1 n] (tset bindings i (gensym)))
36503650- `(fn ,bindings (,f ,(unpack bindings)))))
54595459+ (for [i 1 n]
54605460+ (tset bindings i (gensym)))
54615461+ `(fn ,bindings
54625462+ (,f ,(unpack bindings)))))
3651546336523652- (fn pick-values [n ...]
36533653- "Like the `values` special, but emits exactly n values.
54645464+ (fn pick-values* [n ...]
54655465+ "Evaluate to exactly n values.
3654546636555467 For example,
36565468 (pick-values 2 ...)
36575469 expands to
36585470 (let [(_0_ _1_) ...]
36595471 (values _0_ _1_))"
36603660- (assert (and (= :number (type n)) (>= n 0) (= n (math.floor n)))
36613661- "Expected n to be an integer >= 0")
36623662- (let [let-syms (list)
36633663- let-values (if (= 1 (select :# ...)) ... `(values ,...))]
36643664- (for [i 1 n] (table.insert let-syms (gensym)))
54725472+ (assert (and (= :number (type n)) (<= 0 n) (= n (math.floor n)))
54735473+ (.. "Expected n to be an integer >= 0, got " (tostring n)))
54745474+ (let [let-syms (list)
54755475+ let-values (if (= 1 (select "#" ...)) ... `(values ,...))]
54765476+ (for [i 1 n]
54775477+ (table.insert let-syms (gensym)))
36655478 (if (= n 0) `(values)
36663666- `(let [,let-syms ,let-values] (values ,(unpack let-syms))))))
54795479+ `(let [,let-syms ,let-values]
54805480+ (values ,(unpack let-syms))))))
3667548136683668- (fn lambda [...]
36693669- "Function literal with arity checking.
36703670- Will throw an exception if a declared argument is passed in as nil, unless
36713671- that argument name begins with ?."
54825482+ (fn lambda* [...]
54835483+ "Function literal with nil-checked arguments.
54845484+ Like `fn`, but will throw an exception if a declared argument is passed in as
54855485+ nil, unless that argument's name begins with a question mark."
36725486 (let [args [...]
36735487 has-internal-name? (sym? (. args 1))
36745488 arglist (if has-internal-name? (. args 2) (. args 1))
36755489 docstring-position (if has-internal-name? 3 2)
36763676- has-docstring? (and (> (# args) docstring-position)
54905490+ has-docstring? (and (< docstring-position (length args))
36775491 (= :string (type (. args docstring-position))))
36785492 arity-check-position (- 4 (if has-internal-name? 0 1)
36795493 (if has-docstring? 0 1))
36803680- empty-body? (< (# args) arity-check-position)]
54945494+ empty-body? (< (length args) arity-check-position)]
36815495 (fn check! [a]
36825496 (if (table? a)
36835497 (each [_ a (pairs a)]
36845498 (check! a))
36855499 (let [as (tostring a)]
36863686- (and (not (as:match "^?")) (not= as "&") (not= as "_") (not= as "...")))
55005500+ (and (not (as:match "^?")) (not= as "&") (not= as "_")
55015501+ (not= as "...") (not= as "&as")))
36875502 (table.insert args arity-check-position
36883688- `(assert (not= nil ,a)
36893689- (string.format "Missing argument %s on %s:%s"
36903690- ,(tostring a)
36913691- ,(or a.filename "unknown")
36923692- ,(or a.line "?"))))))
55035503+ `(_G.assert (not= nil ,a)
55045504+ ,(: "Missing argument %s on %s:%s" :format
55055505+ (tostring a)
55065506+ (or a.filename :unknown)
55075507+ (or a.line "?"))))))
55085508+36935509 (assert (= :table (type arglist)) "expected arg list")
36945510 (each [_ a (ipairs arglist)]
36955511 (check! a))
···36975513 (table.insert args (sym :nil)))
36985514 `(fn ,(unpack args))))
3699551537003700- (fn macro [name ...]
55165516+ (fn macro* [name ...]
37015517 "Define a single macro."
37025518 (assert (sym? name) "expected symbol for macro name")
37035519 (local args [...])
37043704- `(macros { ,(tostring name) (fn ,(unpack args))}))
55205520+ `(macros {,(tostring name) (fn ,(unpack args))}))
3705552137063706- (fn macrodebug [form return?]
55225522+ (fn macrodebug* [form return?]
37075523 "Print the resulting form after performing macroexpansion.
37085524 With a second argument, returns expanded form as a string instead of printing."
37095525 (let [handle (if return? `do `print)]
37105526 `(,handle ,(view (macroexpand form _SCOPE)))))
3711552737123712- (fn import-macros [binding1 module-name1 ...]
37133713- "Binds a table of macros from each macro module according to a binding form.
55285528+ (fn import-macros* [binding1 module-name1 ...]
55295529+ "Bind a table of macros from each macro module according to a binding form.
37145530 Each binding form can be either a symbol or a k/v destructuring table.
37155531 Example:
37165532 (import-macros mymacros :my-macros ; bind to symbol
37175533 {:macro1 alias : macro2} :proj.macros) ; import by name"
37183718- (assert (and binding1 module-name1 (= 0 (% (select :# ...) 2)))
55345534+ (assert (and binding1 module-name1 (= 0 (% (select "#" ...) 2)))
37195535 "expected even number of binding/modulename pairs")
37203720- (for [i 1 (select :# binding1 module-name1 ...) 2]
55365536+ (for [i 1 (select "#" binding1 module-name1 ...) 2]
55375537+ ;; delegate the actual loading of the macros to the require-macros
55385538+ ;; special which already knows how to set up the compiler env and stuff.
55395539+ ;; this is weird because require-macros is deprecated but it works.
37215540 (let [(binding modname) (select i binding1 module-name1 ...)
37223722- ;; generate a subscope of current scope, use require-macros
37233723- ;; to bring in macro module. after that, we just copy the
37243724- ;; macros from subscope to scope.
37255541 scope (get-scope)
37263726- subscope (fennel.scope scope)]
37273727- (_SPECIALS.require-macros `(require-macros ,modname) subscope {} ast)
55425542+ ;; if the module-name is an expression (and not just a string) we
55435543+ ;; patch our expression to have the correct source filename so
55445544+ ;; require-macros can pass it down when resolving the module-name.
55455545+ expr `(import-macros ,modname)
55465546+ filename (if (list? modname) (. modname 1 :filename) :unknown)
55475547+ _ (tset expr :filename filename)
55485548+ macros* (_SPECIALS.require-macros expr scope {} binding)]
37285549 (if (sym? binding)
37295550 ;; bind whole table of macros to table bound to symbol
37303730- (do (tset scope.macros (. binding 1) {})
37313731- (each [k v (pairs subscope.macros)]
37323732- (tset (. scope.macros (. binding 1)) k v)))
37333733-55515551+ (tset scope.macros (. binding 1) macros*)
37345552 ;; 1-level table destructuring for importing individual macros
37355553 (table? binding)
37365554 (each [macro-name [import-key] (pairs binding)]
37373737- (assert (= :function (type (. subscope.macros macro-name)))
55555555+ (assert (= :function (type (. macros* macro-name)))
37385556 (.. "macro " macro-name " not found in module "
37395557 (tostring modname)))
37403740- (tset scope.macros import-key (. subscope.macros macro-name))))))
55585558+ (tset scope.macros import-key (. macros* macro-name))))))
37415559 nil)
3742556037435561 ;;; Pattern matching
···37545572 (values condition bindings)))
3755557337565574 (fn match-table [val pattern unifications match-pattern]
37573757- (let [condition `(and (= (type ,val) :table))
55755575+ (let [condition `(and (= (_G.type ,val) :table))
37585576 bindings []]
37595577 (each [k pat (pairs pattern)]
37603760- (if (and (sym? pat) (= "&" (tostring pat)))
37613761- (do (assert (not (. pattern (+ k 2)))
37623762- "expected rest argument before last parameter")
37633763- (table.insert bindings (. pattern (+ k 1)))
37643764- (table.insert bindings [`(select ,k ((or table.unpack
37653765- _G.unpack)
37663766- ,val))]))
37673767- (and (= :number (type k))
37683768- (= "&" (tostring (. pattern (- k 1)))))
37693769- nil ; don't process the pattern right after &; already got it
55785578+ (if (= pat `&)
55795579+ (let [rest-pat (. pattern (+ k 1))
55805580+ rest-val `(select ,k ((or table.unpack _G.unpack) ,val))
55815581+ subcondition (match-table `(pick-values 1 ,rest-val)
55825582+ rest-pat unifications match-pattern)]
55835583+ (if (not (sym? rest-pat))
55845584+ (table.insert condition subcondition))
55855585+ (assert (= nil (. pattern (+ k 2)))
55865586+ "expected & rest argument before last parameter")
55875587+ (table.insert bindings rest-pat)
55885588+ (table.insert bindings [rest-val]))
55895589+ (= k `&as)
55905590+ (do
55915591+ (table.insert bindings pat)
55925592+ (table.insert bindings val))
55935593+ (and (= :number (type k)) (= `&as pat))
55945594+ (do
55955595+ (assert (= nil (. pattern (+ k 2)))
55965596+ "expected &as argument before last parameter")
55975597+ (table.insert bindings (. pattern (+ k 1)))
55985598+ (table.insert bindings val))
55995599+ ;; don't process the pattern right after &/&as; already got it
56005600+ (or (not= :number (type k)) (and (not= `&as (. pattern (- k 1)))
56015601+ (not= `& (. pattern (- k 1)))))
37705602 (let [subval `(. ,val ,k)
37715603 (subcondition subbindings) (match-pattern [subval] pat
37725604 unifications)]
···37765608 (values condition bindings)))
3777560937785610 (fn match-pattern [vals pattern unifications]
37793779- "Takes the AST of values and a single pattern and returns a condition
56115611+ "Take the AST of values and a single pattern and returns a condition
37805612 to determine if it matches as well as a list of bindings to
37815613 introduce for the duration of the body if it does match."
37825614 ;; we have to assume we're matching against multiple values here until we
···37845616 ;; of vals) or we're not, in which case we only care about the first one.
37855617 (let [[val] vals]
37865618 (if (or (and (sym? pattern) ; unification with outer locals (or nil)
37873787- (not= :_ (tostring pattern)) ; never unify _
37883788- (or (in-scope? pattern)
37893789- (= :nil (tostring pattern))))
37903790- (and (multi-sym? pattern)
37913791- (in-scope? (. (multi-sym? pattern) 1))))
56195619+ (not= "_" (tostring pattern)) ; never unify _
56205620+ (or (in-scope? pattern) (= :nil (tostring pattern))))
56215621+ (and (multi-sym? pattern) (in-scope? (. (multi-sym? pattern) 1))))
37925622 (values `(= ,val ,pattern) [])
37935623 ;; unify a local we've seen already
37945624 (and (sym? pattern) (. unifications (tostring pattern)))
···37975627 (sym? pattern)
37985628 (let [wildcard? (: (tostring pattern) :find "^_")]
37995629 (if (not wildcard?) (tset unifications (tostring pattern) val))
38003800- (values (if (or wildcard? (string.find (tostring pattern) "^?"))
38013801- true `(not= ,(sym :nil) ,val))
38023802- [pattern val]))
56305630+ (values (if (or wildcard? (string.find (tostring pattern) "^?")) true
56315631+ `(not= ,(sym :nil) ,val)) [pattern val]))
38035632 ;; guard clause
38043804- (and (list? pattern) (sym? (. pattern 2)) (= :? (tostring (. pattern 2))))
56335633+ (and (list? pattern) (= (. pattern 2) `?))
38055634 (let [(pcondition bindings) (match-pattern vals (. pattern 1)
38065635 unifications)
38073807- condition `(and ,pcondition)]
38083808- (for [i 3 (# pattern)] ; splice in guard clauses
38093809- (table.insert condition (. pattern i)))
38103810- (values `(let ,bindings ,condition) bindings))
38113811-56365636+ condition `(and ,(unpack pattern 3))]
56375637+ (values `(and ,pcondition
56385638+ (let ,bindings
56395639+ ,condition)) bindings))
38125640 ;; multi-valued patterns (represented as lists)
38135641 (list? pattern)
38145642 (match-values vals pattern unifications match-pattern)
···38215649 (fn match-condition [vals clauses]
38225650 "Construct the actual `if` AST for the given match values and clauses."
38235651 (if (not= 0 (% (length clauses) 2)) ; treat odd final clause as default
38243824- (table.insert clauses (length clauses) (sym :_)))
56525652+ (table.insert clauses (length clauses) (sym "_")))
38255653 (let [out `(if)]
38265654 (for [i 1 (length clauses) 2]
38275655 (let [pattern (. clauses i)
38285656 body (. clauses (+ i 1))
38295657 (condition bindings) (match-pattern vals pattern {})]
38305658 (table.insert out condition)
38313831- (table.insert out `(let ,bindings ,body))))
56595659+ (table.insert out `(let ,bindings
56605660+ ,body))))
38325661 out))
3833566238345663 (fn match-val-syms [clauses]
38355664 "How many multi-valued clauses are there? return a list of that many gensyms."
38365665 (let [syms (list (gensym))]
38375666 (for [i 1 (length clauses) 2]
38383838- (if (list? (. clauses i))
38393839- (each [valnum (ipairs (. clauses i))]
38403840- (if (not (. syms valnum))
38413841- (tset syms valnum (gensym))))))
56675667+ (let [clause (if (and (list? (. clauses i)) (= `? (. clauses i 2)))
56685668+ (. clauses i 1)
56695669+ (. clauses i))]
56705670+ (if (list? clause)
56715671+ (each [valnum (ipairs clause)]
56725672+ (if (not (. syms valnum))
56735673+ (tset syms valnum (gensym)))))))
38425674 syms))
3843567538443844- (fn match [val ...]
38453845- "Perform pattern matching on val. See reference for details."
56765676+ (fn match* [val ...]
56775677+ ;; Old implementation of match macro, which doesn't directly support
56785678+ ;; `where' and `or'. New syntax is implemented in `match-where',
56795679+ ;; which simply generates old syntax and feeds it to `match*'.
38465680 (let [clauses [...]
38475681 vals (match-val-syms clauses)]
38485682 ;; protect against multiple evaluation of the value, bind against as
38495683 ;; many values as we ever match against in the clauses.
38503850- (list `let [vals val]
38513851- (match-condition vals clauses))))
56845684+ (list `let [vals val] (match-condition vals clauses))))
56855685+56865686+ ;; Construction of old match syntax from new syntax
56875687+56885688+ (fn partition-2 [seq]
56895689+ ;; Partition `seq` by 2.
56905690+ ;; If `seq` has odd amount of elements, the last one is dropped.
56915691+ ;;
56925692+ ;; Input: [1 2 3 4 5]
56935693+ ;; Output: [[1 2] [3 4]]
56945694+ (let [firsts []
56955695+ seconds []
56965696+ res []]
56975697+ (for [i 1 (length seq) 2]
56985698+ (let [first (. seq i)
56995699+ second (. seq (+ i 1))]
57005700+ (table.insert firsts (if (not= nil first) first `nil))
57015701+ (table.insert seconds (if (not= nil second) second `nil))))
57025702+ (each [i v1 (ipairs firsts)]
57035703+ (let [v2 (. seconds i)]
57045704+ (if (not= nil v2)
57055705+ (table.insert res [v1 v2]))))
57065706+ res))
57075707+57085708+ (fn transform-or [[_ & pats] guards]
57095709+ ;; Transforms `(or pat pats*)` lists into match `guard` patterns.
57105710+ ;;
57115711+ ;; (or pat1 pat2), guard => [(pat1 ? guard) (pat2 ? guard)]
57125712+ (let [res []]
57135713+ (each [_ pat (ipairs pats)]
57145714+ (table.insert res (list pat `? (unpack guards))))
57155715+ res))
57165716+57175717+ (fn transform-cond [cond]
57185718+ ;; Transforms `where` cond into sequence of `match` guards.
57195719+ ;;
57205720+ ;; pat => [pat]
57215721+ ;; (where pat guard) => [(pat ? guard)]
57225722+ ;; (where (or pat1 pat2) guard) => [(pat1 ? guard) (pat2 ? guard)]
57235723+ (if (and (list? cond) (= (. cond 1) `where))
57245724+ (let [second (. cond 2)]
57255725+ (if (and (list? second) (= (. second 1) `or))
57265726+ (transform-or second [(unpack cond 3)])
57275727+ :else
57285728+ [(list second `? (unpack cond 3))]))
57295729+ :else
57305730+ [cond]))
57315731+57325732+ (fn match-where [val ...]
57335733+ "Perform pattern matching on val. See reference for details.
57345734+57355735+ Syntax:
57365736+57375737+ (match data-expression
57385738+ pattern body
57395739+ (where pattern guard guards*) body
57405740+ (where (or pattern patterns*) guard guards*) body)"
57415741+ (assert (not= val nil) "missing subject")
57425742+ (assert (= 0 (math.fmod (select :# ...) 2))
57435743+ "expected even number of pattern/body pairs")
57445744+ (assert (not= 0 (select :# ...))
57455745+ "expected at least one pattern/body pair")
57465746+ (let [conds-bodies (partition-2 [...])
57475747+ match-body []]
57485748+ (each [_ [cond body] (ipairs conds-bodies)]
57495749+ (each [_ cond (ipairs (transform-cond cond))]
57505750+ (table.insert match-body cond)
57515751+ (table.insert match-body body)))
57525752+ (match* val (unpack match-body))))
57535753+57545754+ (fn match-try-step [expr else pattern body ...]
57555755+ (if (= nil pattern body)
57565756+ expr
57575757+ ;; unlike regular match, we can't know how many values the value
57585758+ ;; might evaluate to, so we have to capture them all in ... via IIFE
57595759+ ;; to avoid double-evaluation.
57605760+ `((fn [...]
57615761+ (match ...
57625762+ ,pattern ,(match-try-step body else ...)
57635763+ ,(unpack else)))
57645764+ ,expr)))
3852576538533853- {: -> : ->> : -?> : -?>>
38543854- : doto : when : with-open
38553855- : collect : icollect
38563856- : partial : lambda
38573857- : pick-args : pick-values
38583858- : macro : macrodebug : import-macros
38593859- : match}
57665766+ (fn match-try* [expr pattern body ...]
57675767+ "Perform chained pattern matching for a sequence of steps which might fail.
57685768+57695769+ The values from the initial expression are matched against the first pattern.
57705770+ If they match, the first body is evaluated and its values are matched against
57715771+ the second pattern, etc.
57725772+57735773+ If there is a (catch pat1 body1 pat2 body2 ...) form at the end, any mismatch
57745774+ from the steps will be tried against these patterns in sequence as a fallback
57755775+ just like a normal match. If there is no catch, the mismatched values will be
57765776+ returned as the value of the entire expression."
57775777+ (let [clauses [pattern body ...]
57785778+ last (. clauses (length clauses))
57795779+ catch (if (= `catch (and (= :table (type last)) (. last 1)))
57805780+ (let [[_ & e] (table.remove clauses)] e) ; remove `catch sym
57815781+ [`_# `...])]
57825782+ (assert (= 0 (math.fmod (length clauses) 2))
57835783+ "expected every pattern to have a body")
57845784+ (assert (= 0 (math.fmod (length catch) 2))
57855785+ "expected every catch pattern to have a body")
57865786+ (match-try-step expr catch (unpack clauses))))
57875787+57885788+ {:-> ->*
57895789+ :->> ->>*
57905790+ :-?> -?>*
57915791+ :-?>> -?>>*
57925792+ :?. ?dot
57935793+ :doto doto*
57945794+ :when when*
57955795+ :with-open with-open*
57965796+ :collect collect*
57975797+ :icollect icollect*
57985798+ :fcollect fcollect*
57995799+ :accumulate accumulate*
58005800+ :partial partial*
58015801+ :lambda lambda*
58025802+ :pick-args pick-args*
58035803+ :pick-values pick-values*
58045804+ :macro macro*
58055805+ :macrodebug macrodebug*
58065806+ :import-macros import-macros*
58075807+ :match match-where
58085808+ :match-try match-try*}
38605809 ]===]
38615810 local module_name = "fennel.macros"
38623862- local _ = nil
38633863- local function _0_()
58115811+ local _
58125812+ local function _739_()
38645813 return mod
38655814 end
38663866- package.preload[module_name] = _0_
58155815+ package.preload[module_name] = _739_
38675816 _ = nil
38683868- local env = nil
58175817+ local env
38695818 do
38703870- local _1_0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {})
38713871- _1_0["utils"] = utils
38723872- _1_0["fennel"] = mod
38733873- env = _1_0
58195819+ local _740_ = specials["make-compiler-env"](nil, compiler.scopes.compiler, {})
58205820+ do end (_740_)["utils"] = utils
58215821+ _740_["fennel"] = mod
58225822+ env = _740_
38745823 end
38753875- local built_ins = eval(builtin_macros, {allowedGlobals = false, env = env, filename = "src/fennel/macros.fnl", moduleName = module_name, scope = compiler.scopes.compiler, useMetadata = true})
58245824+ local built_ins = eval(builtin_macros, {env = env, scope = compiler.scopes.compiler, allowedGlobals = false, useMetadata = true, filename = "src/fennel/macros.fnl", moduleName = module_name})
38765825 for k, v in pairs(built_ins) do
38775826 compiler.scopes.global.macros[k] = v
38785827 end
+1-1
vim/.config/nvim/plugin/pack-delayed.vim
···33endif
44let g:loaded_pack_delayed = 1
5566-func! DelayedLoad(...) abort " No abort as we want to continue if any plugin fails
66+func! DelayedLoad(...) " No abort as we want to continue if any plugin fails
77 " Git
88 packadd targets.vim
99